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


8

クエリ結果を保持するために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構文を調べましたが、それは戻り値しか処理できないようです。


2
PL / SQL => Oracle、PgPL / SQL => PostgreSQL。どちらを使用していますか?
Mat

@Mat:それはPL / pgSQLです。
Erwin Brandstetter 2013

回答:


12

PostgreSQLの、すべてのテーブル名の型の名前として機能行タイプ(別名複合型自動) - ないテーブル型、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には明示的なカーソルもあります。

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

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

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


2
また、テーブルタイプを返す場合は、次のように言うこともできますCREATE FUNCTION footest() RETURNS SETOF foo LANGUAGE PLPGSQL AS $$...
Chris Travers

代わりに、複合タイプに適用される制限なし(制約なしなど)でテーブルを作成できるのに、なぜ「複合タイプ」の機能があるのでしょうか。私が見る複合型を使用する唯一の意味のある方法は、そのためのテーブル全体を作成する代わりに、関数からいくつか(またはいくつか)のパラメーターを返すことです。
SaneDeveloper
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.