[pgsql-jp: 39933] Re: PL/pgSQLでのプロシジャ実装について

takayuki-maruyama @ nova-system.com takayuki-maruyama @ nova-system.com
2009年 7月 20日 (月) 08:45:07 JST


お世話になります。丸山です。

ご指摘いただいた件、説明不足で失礼しました。
以下、長文失礼します。

やりたいこととしては、例えばテーブルtbl_hogeについて
CREATE OR REPLACE FUNCTION sp_demo(
IN a INTEGER,
IN b INTEGER,
IN c INTEGER,
・・・・
というパラメータを指定した時に、
・パラメータaが指定されたときは
 SELECT x, y, z FROM tbl_hoge WHERE a = $1;
・パラメータaとbが指定されたときは
 SELECT x, y, z FROM tbl_hoge WHERE a = $1 AND b = $2;
・パラメータcが指定されたときは
 SELECT x, y, z FROM tbl_hoge WHERE c = $3
のようにパラメータの指定内容で検索条件を変えて、x, y, zの結果を複数行で
得ようとしています。


現在は、次のようにプロシジャを記述しています。

CREATE OR REPLACE FUNCTION sp_demo(
IN a INTEGER,
IN b INTEGER,
IN c INTEGER,
・・・・
OUT x integer,
OUT y character varying,
OUT z character varying
) RETURNS SETOF record AS
$BODY$
DECLARE
    sqlstr      VARCHAR;
    wherestr    VARCHAR;
    rec         RECORD;
BEGIN
    sqlstr := 'SELECT x, y, z';
    sqlstr := sqlstr || ' FROM tbl_hoge';
    IF $1 != 0 THEN
        wherestr := wherestr || ' a = ' || $1;
    END IF;
    ・・・・
    sqlstr := sqlstr || wherestr;
    EXECUTE sqlstr;
    RETURN NEXT;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;

これについて、次のように呼び出しているのですが、実行結果は返ってくるもの
の1行のみで、しかも内容はすべて空となってしまいます。
SELECT * FROM sp_demo(1, 2, 3);

複数行を取得したいので、OUTパラメータを除いた上で上記EXECUTEの部分を
    FOR rec IN EXECUTE sqlstr LOOP
        RETURN NEXT rec;
    END LOOP;
    RETURN;
とするのが本来かとも思ったのですが、今度は実行時に次のようなエラーとなっ
てしまいます。
SELECT * FROM sp_demo(1, 2, 3);
ERROR:  a column definition list is required for functions returning
"record"

ネットなどでいろんな情報を見る限りでは、今回のように複数行・複数カラムを
動的SQLで取得しているケースはないようで、そもそもがPL/pgSQLの仕様上ムリ
なのかとも思っています。
ただ、その辺りの判断もつけかねていますので、もし同様の経験をされた方がい
らっしゃれば、アドバイスいただければと思っています。


それでは、よろしくお願いします。

chuuken kenkou さんは書きました:
> chuukenです。
> 
>> <制約>
>> ・実行結果は結果集合(複数行)で受け取りたい
>> ・検索項目(複数)をパラメータとして渡し、値が設定されている項目を
>>  キーにして入力内容でデータを検索する
>>  ※ロジックが煩雑になるので、プロシジャ内で動的SQLを組立&実行する
>>   方向で試しています
> 
> もう少し、やりたいことを具体的に説明できませんか?
> 
>> <現状>
>> ネット上の情報を参考にいろいろ試しているのですが、まともな出力結果1つ得
>> られていません。
>> もしかして、実装自体不可能なのでは?とも思っています....
>> ○RETURNS SETOF RECORDを指定+動的SQLをEXECUTEで実行後RETURN NEXTを指定
>>  →値が何も返らない
> 
> どういう関数を定義し、どのように呼び出しているのでしょうか?
> 「値が何も返らない」とは、具体的にどうなるのでしょう?
> 「何かエラーが起こっている」のに、拾えていないといったことはありませんか?




pgsql-jp メーリングリストの案内