- 締切済み
pl/pgsqlで再帰呼び出しは可能でしょうか。
pl/pgsqlで再帰呼び出しは可能でしょうか。 PostgreSQLのバージョンは9.2.3です。 作成しているファンクションは正方形の中心座標を求めてInsertするものです。 指定した回数だけ、再帰的に正方形を4分割にどんどん細分化していき、 それぞれの正方形の中心座標をInsertします。 4分割にした正方形をそれぞれ以下のように番号を振って説明します。 左上・・・(1) 右上・・・(2) 左下・・・(3) 右下・・・(4) 元の正方形を求めた後、(1)→(2)→(3)→(4)の順に再帰的にファンクションを呼び出します。 パラメータを「3回」以上にした場合は、(1)についてもまた4分割していきます。 ここで、パラメータを「1回」とした場合は、元の正方形の中心座標は当然Insertできます。 パラメータを「2回」とした場合、(1)の正方形の中心座標も求まりますが、 (1)の正方形については再帰の最終処理のため、Insert後にRETURNすることで エラーとなっているのか、1つ目の正方形のレコードも(2)の正方形のレコードも Insertされていません。 さらにはその「RETURN句」が元のファンクションすら「終了」させているようで、 (2)、(3)、(4)の正方形の処理が行われません。 このように再帰呼び出しをしたいと思っても、再帰中の処理を終わらせ、 呼び出し元に戻らせるはずのRETURN句が、一番最初のファンクションの「終了」と 理解されてしまい、pl/pgsqlでは再帰呼び出しは実現できないのでしょうか。 ファンクションのイメージは以下の通りです。 CREATE OR REPLACE FUNCTION Insert_squre( IN kaisuu INT, --再帰的に呼び出す回数 IN count INT, --再帰回数をカウント IN X1 INT, --正方形の左上の頂点のX座標 IN Y1 INT, --正方形の左上の頂点のY座標 IN X2 INT, --正方形の右下の頂点のX座標 IN Y2 INT --正方形の右下の頂点のY座標 ) RETURNS void AS $$ DECLARE /* 変数定義 */ ・・・・・ BEGIN /* 中心座標を求める */ ・・・・・ /* 中心座標をInsert */ ・・・・・ /* kaisuu=countならばRETURN */ ・・・・・ /* (1)の正方形について再帰処理 */ select Insert_squre( IN kaisuu INT, --再帰的に呼び出す回数 IN count+1 INT, --再帰回数をカウント IN X1 INT, --正方形の左上の頂点のX座標 IN Y1 INT, --正方形の左上の頂点のY座標 IN X3 INT, --正方形の右下の頂点のX座標 IN Y3 INT --正方形の右下の頂点のY座標 ); /* (2)の正方形について再帰処理 */ ・・・・・ /* (3)の正方形について再帰処理 */ ・・・・・ /* (4)の正方形について再帰処理 */ ・・・・・ RETURN; END; $$ LANGUAGE PLpgSQL;
- みんなの回答 (1)
- 専門家の回答
みんなの回答
- yamada59
- ベストアンサー率74% (29/39)
関数の呼び出し方に問題があります。関数の呼び出し時には IN / OUT パラメータやデータ型の指定は不要です。 /* (1)の正方形について再帰処理 */ SELECT insert_square(kaisuu, count + 1, x1, y1, x3, y3); などと書き換えるとどうなるでしょうか。(2) ~ (4) についても同様です。 また、エラーメッセージが出力されていれば、提供してもらったほうが回答しやすいです。 あと、PostgreSQL には幾何データ型や幾何関数があるので、それらを使ったほうが関数をシンプルにできると思います。例えば、中心の座標を求めるcenterといった関数もあります。
補足
ご回答ありがとうございます! >関数の呼び出し方に問題があります。 >関数の呼び出し時には IN / OUT パラメータやデータ型の指定は不要です。 すみません、私の記載ミスで、再帰呼び出しの箇所にIN/OUT及びデータ型は記載していません。 >また、エラーメッセージが出力されていれば、提供してもらったほうが回答しやすいです。 初歩的な質問で申し訳ないのですが、標準出力には何も出力されません。 エラーとなっていることは確かなのですが、メッセージはどうすれば確認できますでしょうか。 >あと、PostgreSQL には幾何データ型や幾何関数があるので そうなんですね。教えて頂きありがとうございます!参考になります。