web-dev-qa-db-ja.com

PL / pgSQLでテーブル型の変数を宣言する

クエリ結果を保持するためにPL/pgSQLで型tableの変数を宣言する方法があるかどうか疑問に思っていますか?たとえば、次のように表現するにはどうすればよいですか。

q1 = select * from foo;
q2 = select * from bar;
for t1 in q1:
  for t2 in q2:
    -- do something with t1 and t2

Return next構文を調べましたが、それは戻り値しか処理できないようです。

8
JRR

PostgreSQLでは、すべてのテーブル名行の型名として機能しますtype(aka composite type )自動-notテーブルタイプPostgresには「テーブル型」や「テーブル変数」はありません( 型付きテーブルはあります )。
PL/pgSQL でその型の変数を宣言できます。

CREATE FUNCTION foo()
 RETURNS void LANGUAGE plpgsql AS
$func$
DECLARE
  q1 foo;  -- "foo" ...
  q2 bar;  -- ... and "bar" are existing (visible) table names
BEGIN

FOR q1 IN 
   SELECT * from foo
LOOP
   FOR q2 IN 
      SELECT * from bar
   LOOP
       -- do something with q1 and q2
       -- since q1 and q2 are well known types, you can access columns
       -- with attribute notation. Like: q1.col1
   END LOOP;
END LOOP;

END
$func$

FORループは、組み込みカーソルで機能します。 plpgsqlには明示的な cursors もあります。

ジェネリック型 record の変数を宣言することもできます。割り当て時に任意の行タイプを自動的に取得できます。ただし、特別なルールが適用されます。必ずリンクをたどり、マニュアルの章を読んでください!

多くの場合、関数がSETOF <table name>を返すと便利ですが、SETOF recordを返すのはそれほど便利ではありません。システムは、関数がこのように返すものを認識していないため、呼び出しごとに列定義リストを追加する必要があります。それは苦痛です。 table functionsin the manual の詳細。

ただし、プレーンSQLを使用したより効率的なソリューションがしばしばあります。ループは、純粋なSQLで複数のスキャンが必要な場合に、1つのスキャンで物事を実行できる最後の手段の尺度です。

11