[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 メーリングリストの案内