2009年7月22日

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

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

2009/07/20 8:45 に <takayuki-maruyama@xxxxx> さんは書きました:
> お世話になります。丸山です。
>
> ご指摘いただいた件、説明不足で失礼しました。
> 以下、長文失礼します。
>

> やりたいこととしては、例えばテーブル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@xxxxx/ishida@xxxxx>


投稿者 xml-rpc : 2009年7月22日 10:50
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/86865
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。