エラー:セットを受け入れることができないコンテキストで呼び出されたset_valued関数。どんな内容ですか?


11

私はubuntu 12.04でPostgresql 9.1を使用しています。

私の質問へのクレイグの回答に触発されたsetofタイプまたはsetofレコードの連結私はreturn querysetof recordこのplpgsql関数に、、およびシリーズジェネレーターを使用するとうまくいくと思いました:

create or replace function compute_all_pair_by_craig(id_obj bigint)
    returns setof record as $$
begin
    return query select o.id, generate_series(0,o.value) from m_obj as o;     
end;
$$    language plpgsql;

実行中にエラーが発生します:

ERROR: set_valued function called in context that cannot accept a set

なにが問題ですか ?Craigとは逆に、関数に返すように指示しますsetof record

私はCraigとまったく同じように機能する何かを実現できます。つまり、型create type pair_id_value as (idx bigint, value integer)を定義し、plpgsql関数がのsetof of pair_id_value代わりにを返すようにしsetof recordます。

しかし、この実用的な解決策を使用しても、なぜselect id, generate_series(0,13)単独で2つの列に結果が返されるのかはまだわかりません...逆に、関数(setof pair_id_valueを返す)を呼び出すと、フィールドが次のように見える1つの列だけにreturn query select id, generate_series(0,my_obj.value) from my_obj結果が返されますこの「(123123,0)」「(123123,1)」「(123123,2)」(3行)は明らかにタプルです。

一時テーブルを作成する必要がある/すべきですか?


コンパイルされないため、実行している関数の正確なテキストにすることはできません。後にセミコロンが余分にBEGINあり、後にセミコロンがないRETURN QUERY。これらのエラーを修正した後record、戻るときにエラーを確認します。答えで説明します。
クレイグリンガー2013年

@CraigRingerセミコロンを元に戻しました。
ステファンRolland 2013年

回答:


7

エラーメッセージはあまり役に立ちません。

regress=> SELECT * FROM  compute_all_pair_by_craig(100);
ERROR:  a column definition list is required for functions returning "record"
LINE 1: SELECT * FROM  compute_all_pair_by_craig(100);

しかし、クエリを言い換えて適切なセットを返す関数として呼び出すと、実際の問題がわかります。

regress=> SELECT * FROM compute_all_pair_by_craig(100);
ERROR:  a column definition list is required for functions returning "record"
LINE 1: SELECT * FROM compute_all_pair_by_craig(100);

パラメータリストSETOF RECORDなしで使用している場合OUTは、呼び出しステートメントで結果を指定する必要があります。例:

regress=> SELECT * FROM compute_all_pair_by_craig(100) theresult(a integer, b integer);

ただし、RETURNS TABLEまたはOUTパラメータを使用する方がはるかに優れています。前者の構文では、関数は次のようになります。

create or replace function compute_all_pair_by_craig(id_obj bigint)
    returns table(a integer, b integer) as $$
begin
    return query select o.id, generate_series(0,o.value) from m_obj as o;     
end;
$$ language plpgsql;

これはSELECTリストのコンテキストで呼び出すことができ、型を明示的に作成したり、呼び出しサイトで結果構造を指定したりせずに使用できます。


質問の後半については、最初のケースでSELECTリストの2つの個別の列が指定されているのに対して、2番目のケースでは単一の複合が返されます。実際に結果を返す方法ではなく、関数を呼び出す方法に関係しています。サンプル関数を作成すると:

CREATE OR REPLACE FUNCTION twocols() RETURNS TABLE(a integer, b integer) 
AS $$ SELECT x, x FROM generate_series(1,5) x; $$ LANGUAGE sql;

セットを返す関数を呼び出す2つの方法の違いがわかります。SELECTリストでは、風変わりな動作をするPostgreSQL固有の非標準拡張機能です。

regress=> SELECT twocols();
 twocols 
---------
 (1,1)
 (2,2)
 (3,3)
 (4,4)
 (5,5)
(5 rows)

またはより標準的な方法でテーブルとして:

regress=> SELECT * FROM twocols();
 a | b 
---+---
 1 | 1
 2 | 2
 3 | 3
 4 | 4
 5 | 5
(5 rows)

テストされたばかりで、完璧に動作します。そして、私はこの構文がで好きreturns tableです。
ステファンRolland 2013年

@StephaneRolland質問の後半の説明も更新しました。
クレイグリンガー2013年

サポートのためのthx。今でははるかに明確です。
ステファンRolland 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.