我想做这样的事情:
CREATE OR REPLACE FUNCTION ff(int, text) RETRUNS integer AS $$
DECLARE
r text;
BEGIN
FOR r IN SELECT string_to_array($2, ',')
LOOP
INSERT INTO test(i, t) VALUES($1, r);
END LOOP;
RETRUN 0;
END
$$LANGUAGE pgsql;
我希望使用SELECT ff(3, 'a,b');
这个功能可以做到
INSERT INTO test(i, t) VALUES(3, 'a');
INSERT INTO test(i, t) VALUES(3, 'b');
答案 0 :(得分:10)
自PostgreSQL 9.1以来,您可以使用FOREACH LOOP迭代数组。来自documentation的示例:
CREATE FUNCTION sum(int[]) RETURNS int8 AS $$
DECLARE
s int8 := 0;
x int;
BEGIN
FOREACH x IN ARRAY $1
LOOP
s := s + x;
END LOOP;
RETURN s;
END;
$$ LANGUAGE plpgsql;
对你来说,mu's answer更好,但是大多数通过标题找到这个问题的用户都会更喜欢我的答案。
答案 1 :(得分:7)
您不需要循环,可以使用unnest
将数组从string_to_array
转换为一组行,然后使用简单的insert ... select
构造:
create or replace function ff(int, text) returns integer as $$
begin
insert into test(i, t)
select $1, s
from unnest(string_to_array($2, ',')) as dt(s);
return 0;
end
$$ language plpgsql;
我还纠正了一些拼写错误(RETRUNS
,RETRUN
和pgsql
)。
您也可以使用regexp_split_to_table
:
create or replace function ff(int, text) returns integer as $$
begin
insert into test(i, t)
select $1, s
from regexp_split_to_table($2, ',') as dt(s);
return 0;
end
$$ language plpgsql;
如果你陷入了8.1岁的时代并且对此无能为力,那么也许这样的事情会起作用:
create or replace function ff(int, text) returns integer as $$
declare
a text[];
i int;
begin
select string_to_array($2, ',') into a;
i := 1;
loop
if i > array_upper(a, 1) then
exit;
else
insert into test(i, t) values($1, a[i]);
i := i + 1;
end if;
end loop;
return 0;
end
$$ language plpgsql;
我认为这应该适用于8.1但我无法访问8.1进行检查。