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

ISHIDA Akio iakio @ mono-space.net
2009年 7月 22日 (水) 10:50:26 JST


こんにちは。石田@苫小牧市と申します。

2009/07/20 8:45 に <takayuki-maruyama @ nova-system.com> さんは書きました:
> お世話になります。丸山です。
>
> ご指摘いただいた件、説明不足で失礼しました。
> 以下、長文失礼します。
>
> やりたいこととしては、例えばテーブル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の結果を複数行で
> 得ようとしています。
>
>
(中略)
>
> これについて、次のように呼び出しているのですが、実行結果は返ってくるもの
> の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"
>

この方法で問題無いと思います。
この時、関数のプロトタイプでOUTパラメータを指定されていないと
思うので、呼び出す側のSQLで、
SELECT * FROM sp_demo(1, 2, 3) AS s(x int, y varchar, z varchar);
とすることで実行できると思います。

あるいは、OUTパラメータを指定した場合は、
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
...
   FOR rec IN EXECUTE sqlstr LOOP
       x := rec.x;
       y := rec.y;
       z := rec.z;
       RETURN NEXT;
   END LOOP;
...

のように、OUTパラメータに値を代入しつつ、
引数を指定しないRETURN NEXTを呼び出します。

# 8.4であれば、RETURN QUERY EXECUTEが使えそうですが。

-- 
ISHIDA Akio <iakio @ mono-space.net/ishida @ cycleof5th.com>



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