13

integer[] パラメーターを引数として取り、このパラメーターを使用して IN 句でクエリをループで実行する関数を作成する方法。ループでは、次の選択を実行し、このクエリの結果を返したいと思います。

そんな感じ:

CREATE OR REPLACE FUNCTION function_which_i_want(my_argument integer[]) RETURNS my_schema_and_table[] AS
$BODY$
DECLARE
result my_schema_and_table[];
BEGIN
FOR l IN SELECT * FROM table2 WHERE id in (my_argument) LOOP
SELECT * FROM my_schema_and_table;
END LOOP;
END;
...

ループ内の各選択の結合を取得したい。1 つの巨大な結合結果。これは可能ですか?助けてください。

4

2 に答える 2

12

PL/pgSQL 関数

質問のギャップを埋めると、次のようになります。

CREATE OR REPLACE FUNCTION func1(_arr integer[])
  RETURNS SETOF target_table LANGUAGE plpgsql AS
$func$
DECLARE
    l record;
BEGIN

FOR l IN
    SELECT *
    FROM   lookup_table
    WHERE  some_id = ANY(_arr)
LOOP
    RETURN QUERY
    SELECT *
    FROM   target_table
    WHERE  link_id = l.link_id;
END LOOP;

END
$func$;
  • 結果を返したい場合はSELECT * FROM my_schema_and_table;、この関数全体を別の方法で処理する必要があります。次のように宣言します。RETURNS SETOF target_table

  • 配列ではなく、SETからの行が実際に必要だと仮定しますか?target_table

  • INコンストラクトを に書き換え= ANY(_arr)ます。これは、配列パラメーターを直接使用する方法です。内部的には、PostgreSQL は IN 式を= ANY()とにかくに書き換えます。でテストしEXPLAIN ANALYZEて、自分の目で確かめてください。
    または、 @Clodoaldo が示すように、コンストラクト withunnest()を使用して、結果のテーブルに結合します。これは、長い配列の方が高速です。

単純化して単純な SQL 関数にする

上記はまだ無意味に考案されています。同じことを行う SQL 関数に単純化します。

CREATE OR REPLACE FUNCTION func2(_arr integer[])
  RETURNS SETOF target_table LANGUAGE sql AS
$func$
SELECT t.*
FROM   (SELECT unnest($1) AS some_id) x
JOIN   lookup_table l USING (some_id) 
JOIN   target_table t USING (link_id); -- assuming both tables have link_id
$func$

電話:

SELECT * FROM func2('{21,31}'::int[]);
于 2012-10-19T18:44:55.717 に答える
4
CREATE OR REPLACE FUNCTION function_which_i_want(my_argument integer[])
RETURNS my_schema_and_table[] AS
$BODY$
DECLARE
result my_schema_and_table[];
BEGIN

for l in 
    select t.*
    from
        table2 t
        inner join
        unnest(my_argument) m(id) on m.id = t.id
loop
    SELECT * FROM my_schema_and_table;
END LOOP;
END;
于 2012-10-18T14:04:51.903 に答える