[pgsql-jp: 35174] PL/pgSQLの再帰処理の基本について
小川 修
shuogawa @ mister.co.jp
2005年 4月 4日 (月) 14:55:52 JST
いつも勉強させて頂いております。
バージョン8よりPostgreSQLを利用し始めた小川と申します。
これまでは主にMySQLを利用しておりましたが、
PostgreSQLの提供する様々な機能に触れるにつれ、
アプリケーション開発方法の選択肢が増えた印象をうけております。
引き続き勉強して行きたいと考えておりますので、よろしくお願いします。
今回メールさせて頂きましたのは
PL/pgSQLの再帰関数についてです。
過去に話題になっております内容であり、
過去ログやPostgreSQL完全攻略ガイド改定第四版などを参考に、
実装を試みているのですが、私の知識不足でうまく動作させる事が出来ません。
実現したいことは下記の通りです
全国をルートとしました、地域の階層構造を
テーブル名をtestとし
カラムを
id:シーケンスによる通し番号
parent:親のid
name:地域の名前
flag:変更対象のカラム
とし、表現しております。
テーブル内のデータは下記の用になっております。
id parent name flag
---------------------------------------
1 NULL 全国 0
2 1 関東 0
3 2 東京 0
4 3 新宿 0
5 3 渋谷 0
6 3 六本木 0
今回、東京以下のレコードのflagを1に変更することになりました。
正しい変更が行われた場合、以下のようになります。
id parent name flag
---------------------------------------
1 NULL 全国 0
2 1 関東 0
3 2 東京 1
4 3 新宿 1
5 3 渋谷 1
6 3 六本木 1
この変更を再帰関数にて実装したいと考えおります。
私が作成した関数は以下の通りです。
-------------------------------------------------------------
CREATE OR REPLACE FUNCTION "public"."func_test" (integer) RETURNS boolean
AS'
declare
var1 alias for $1;
var_id integer;
var_record record;
begin
--引数のidのflagを1に変更
UPDATE test set flag=1 where id=var1;
--子階層を検索
FOR var_record IN select * from test where parent=var1 LOOP
var_id:=var_record."id";
--子階層のidを引数として、再帰呼び出しを実行
execute func_test(var_id);
END LOOP;
return;
end;
'LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;
--------------------------------------------------------------
状況としましては、この関数を実行すると
ERROR: syntax error at end of input at character 8
とエラーが発生します。
また
戻り値にbooleanを指定している為、return true;と記述すると
---------------------------------------------------------------
CREATE OR REPLACE FUNCTION "public"."func_test" (integer) RETURNS boolean
AS'
declare
var1 alias for $1;
var_id integer;
var_record record;
begin
--引数のidのflagを1に変更
UPDATE test set flag=1 where id=var1;
--子階層を検索
FOR var_record IN select * from test where parent=var1 LOOP
var_id:=var_record."id";
--子階層のidを引数として、再帰呼び出しを実行
execute func_test(var_id);
END LOOP;
return true;
end;
'LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;
--------------------------------------------------------------------
ERROR: syntax error at or near "t" at character 1
のエラーが発生します。
気づいた点としましては
過去ログや書籍で紹介されている、再帰関数の多くに、RETURN NEXT文が入っているが、
私の場合はレコードを返す訳ではないため、RETURN NEXTをつかっていないことです。
これは問題でしょうか?
その他、特に原因を発見することが出来ず、メールさせて頂きました。
アドバイスよろしくお願い致します。
小川 修
pgsql-jp メーリングリストの案内