我有一个有两列的表。
示例:
create table t1
(
cola varchar,
colb varchar
);
现在我想从函数中插入行。
在函数中:我想使用两个varchar
类型的参数将值插入上表中。我传递的字符串插入表中。
我将两个字符串作为参数传递给函数:
参数:
cola varchar = 'a,b,c,d';
colb varchar = 'e,f,g,h';
上述参数必须像这样插入表中:
cola colb
----------------
a e
b f
c g
d h
create or replace function fun_t1(cola varchar,colb varchar)
returns void as
$body$
Declare
v_Count integer;
v_i integer = 0;
v_f1 text;
v_cola varchar;
v_colb varchar;
v_query varchar;
Begin
drop table if exists temp_table;
create temp table temp_table
(
cola varchar,
colb varchar
);
v_Count := length(cola) - length(replace(cola, ',', ''));
raise info '%',v_Count;
WHILE(v_i<=v_Count) LOOP
INSERT INTO temp_table
SELECT LEFT(cola,CHARINDEX(',',cola||',',0)-1)
,LEFT(colb,CHARINDEX(',',colb||',',0)-1);
cola := overlay(cola placing '' from 1 for CHARINDEX(',',cola,0));
colb := overlay(colb placing '' from 1 for CHARINDEX(',',colb,0));
v_i := v_i + 1;
END LOOP;
for v_f1 IN select * from temp_table loop
v_cola := v_f1.cola; /* Error occurred here */
v_colb := v_f1.colb;
v_query := 'INSERT INTO t1 values('''||v_cola||''','''||v_colb||''')';
execute v_query;
end loop;
end;
$body$
language plpgsql;
注意:在我根据要求使用temp_table
的函数中
我还在我没有在这里展示的功能中用于其他用途。
通话功能:
SELECT fun_t1('a,b,c','d,e,f');
收到错误:
missing FROM-clause entry for table "v_f1"
答案 0 :(得分:1)
使用split_part()
尝试这种方式: -
create or replace function ins_t1(vala varchar,valb varchar,row_cnt int) returns void as
$$
BEGIN
FOR i IN 1..row_cnt LOOP -- row_cnt is the number rows you need to insert (ex. 4 or 5 or whatever it is)
insert into t1 (cola,colb)
values (
(select split_part(vala,',',i))
,(select split_part(valb,',',i))
);
END LOOP;
END;
$$
language plpgsql
函数调用:select ins_t1('a,b,c,d','e,f,g,h',4)
正如 mike-sherrill-cat-recall 在他的回答中说regexp_split_to_table
create or replace function fn_t1(vala varchar,valb varchar) returns void
as
$$
insert into t1 (cola, colb)
select col1, col2 from (select
trim(regexp_split_to_table(vala, ',')) col1,
trim(regexp_split_to_table(valb, ',')) col2)t;
$$
language sql
函数调用:select fn_t1('a,b,c,d','e,f,g,h')
答案 1 :(得分:1)
如果没有令人信服的理由为此使用函数,您可以使用正则表达式拆分文本。在这里,我将您的参数表达为一个公用表表达式,但这只是为了方便。
with data (col1, col2) as (
select 'a, b, c, d'::text, 'e, f, g, h'::text
)
select
trim(regexp_split_to_table(col1, ',')) as col_a,
trim(regexp_split_to_table(col2, ',')) as col_b
from data;
col_a col_b -- a e b f c g d h
如果是使用函数的一个令人信服的理由,只需在SELECT语句周围包装一个函数定义。
create function strings_to_table(varchar, varchar)
returns table (col_a varchar, col_b varchar)
as
'select trim(regexp_split_to_table($1, '','')),
trim(regexp_split_to_table($2, '',''));'
language sql
stable
returns null on null input;
select * from strings_to_table('a,b,c,d', 'e,f, g, h');
col_a col_b -- a e b f c g d h
我个人的偏好是通常来构建这样的函数来返回表而不是插入表中。要插入,我通常会编写一个这样的SQL语句。
insert into foo (col_a, col_b)
select col_a, col_b from strings_to_table('a,b,c,d', 'e,f,g,h');
答案 2 :(得分:1)
最简单的方法就是使用plpython。
create or replace function fill_t1(cola varchar, colb varchar) returns void as $$
for r in zip(cola.split(','), colb.split(',')):
plpy.execute(plpy.prepare('insert into t1(cola, colb) values ($1, $2)', ['varchar', 'varchar']), [r[0], r[1]])
$$ language plpythonu;
结果:
# create table t1 (cola varchar, colb varchar);
CREATE TABLE
# select fill_t1('1,2,3', '4,5,6');
fill_t1
---------
(1 row)
# select * from t1;
cola | colb
------+------
1 | 4
2 | 5
3 | 6
(3 rows)
您可以在此处阅读有关Python zip 功能的信息:https://docs.python.org/2/library/functions.html#zip