5

私はこのようなことをしたい:

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');
4

2 に答える 2

11

PostgreSQL 9.1 以降、FOREACH LOOP を使用して配列を反復処理できます。ドキュメントの例:

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 の回答の方が優れていますが、この質問をタイトルで見つけたほとんどのユーザーは、私の回答を好むでしょう。

于 2014-05-14T09:03:11.067 に答える
8

そのためのループは必要ありません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;

また、途中でいくつかのタイプミス ( RETRUNSRETRUN、および)を修正しました。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 にアクセスできません。

于 2012-08-24T03:44:37.017 に答える