PL/pgSQL 引数の数に制限がありますか?

このQ&Aのポイント
  • PL/pgSQL を使用して更新処理を行いたいですが、パラメータの数が多すぎるためエラーが発生しています。
  • 可変長引数を使用すると、データベースには定義できますが、実行時に同様のエラーが発生します。
  • PL/pgSQL の引数の数を制限する設定や対策があれば教えてください。
回答を見る
  • ベストアンサー

PL/pgSQL 引数の数

PL/pgSQL を使用し更新処理を行いたいのですが、 パラメータの数が多すぎるのか 以下のエラーでデータベースにファンクションを定義出来ません。 ERROR: functions cannot have more than 100 arguments SQLステート:54023 可変長引数で作成すると、データベースに定義は出来るのですが ファンクション実行時に同様のエラーが発生し更新処理が行えません。 PL/pgSQL の引数を100以上使用出来る様にする設定等、存在するのであれば 教えて頂きたいです。 環境は以下の内容です。 CentOS-6.2-x86_64 Apache/2.2.15 PostgreSQL 9.1.3 PHP Version 5.3.3 (PDOを使用しています)

質問者が選んだベストアンサー

  • ベストアンサー
  • yamada59
  • ベストアンサー率74% (29/39)
回答No.1

100 以上の引数をもった関数を定義できるようにするには、ソースコードを修正してコンパイルしなおす必要があります。 ヘッダファイル src/include/pg_config_manual.h 内の定数 FUNC_MAX_ARGS を修正してください。ソースコードのコメントには約 600 まで増やせるということです。 100 以上の引数をもつ関数を定義すること自体、設計に何らかの問題がありそうなので、そちらを見なおしたほうがよいと思います。 あるいは、引数を配列や複合型で渡すことを考えたほうがいいかもしれません。

kozax05
質問者

お礼

回答ありがとうございます。 ご指摘の通りファンクションの設計に問題があると思います。 MySqlよりコンバートしているのですが、トランザクションの各カラムをすべてファンクションに送り、ファンクション内で各テーブルの更新及びトランザクションの追加処理を行っているため今回ご質問させて頂いた現象が発生してしまいました。 トランザクションの追加処理はPHP側で行いトリガで各テーブルの更新ファンクションをコールする形に修正しようと思います。

関連するQ&A

  • PL/pgSQLの直接実行

    PL/pgSQLのことで教えてください。 これまで SQL Server を使っていましたが、PostgreSQL に移行しています。 Npgsql で、VB.Net から接続しようと思っています。 PL/pgSQLで、ストアドファンクションなどを定義するのではなく、PL/pgSQLスクリプトを 直接実行することはできないのでしょうか? SQL Server では、T-SQLのスクリプトを直接実行できました。 例えば ManagementStudioのクエリ実行画面にスクリプトを入力して実行したり、 VBからだと、SqlCommand の CommandText に T-SQLを書いて実行したり、という ことです。 pgAdminIIIのSQLエディタや、NpgsqlのNpgsqlCommandで同様のことをやろうとすると エラーになります。 何か良い方法があるのでしょうか?

  • pl/pgsqlでの、エラーコードとファイル操作の方法

    pl/pgsqlのFunctionで、ファイル操作はできますか? また、FunctionでException発生時にエラーコードやエラーメッセージは取得できますか? Windows,PostgreSQL8.2.3です。

  • PL/pgSQLについて

    お世話になっております。 PL/pgSQLでPostgreSQLのあるテーブルにinsertがかかったら、別のテーブルをtriggerを使ってupdateする構文を書いていますが、上手くいきません。 insertを実行すると、変数が割り当てられていない旨が表示されます。 サンプルは以下の通り DROP FUNCTION k_trig(); CREATE FUNCTION k_trig() RETURNS OPAQUE AS' DECLARE ov1 RECORD; ov2 RECORD; BEGIN SELECT * FROM 個別集計 INTO ov1 WHERE id = new.id; UPDATE 個別集計 SET a1 = ov1.a1 + new.a1, a2 = ov1.a2 + new.a2, a3 = ov1.c + new.a3 WHERE id = new.id; *****以下省略 insert実行 ↓ 「record ov1 is unassigned yet」と表示されます。 declareで宣言しているのですが・・・ 何が原因か教えてください

  • 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;

  • 引数なしの関数で疑問です

    とほほのjavascriptで勉強しています。 http://www.tohoho-web.com/js/function.htm#objFunction ここの function goukei() { var ans = 0; for (i = 0; i < goukei.arguments.length; i++) { ans += goukei.arguments[i]; } return(ans); } sum = goukei(1, 2, 3, 4, 5); goukei関数を定義したときの引数は、なしなのに goukei関数を呼び出すとき、goukei(1, 2, 3, 4, 5)と、このように5つも引数を指定しています。 Javaでは、こんな呼び出し方をすれば、コンパイルエラーになりますよね。 javascriptでは、引数なしで関数を宣言しても、呼び出すときに、好きな個数の引数を渡せるのですか? 「javascript 引数 省略」とか、「javascript 引数なし」とかいろいろググッてみたのですが 肝心の、javascriptでは引数なしにして宣言しても、呼び出すとき、好きな個数の引数つけて呼び出しても大丈夫。みたいな、確認したい記述はみつかりませんでした。 javascriptでは、このような書き方もできるということでしょうか。

  • ストアドプロシージャの引数にフィールド名を指定したい

    以下のようにストアドプロシージャを作成し、 ------------------------------------------------------------ CREATE FUNCTION test(integer) RETURNS integer AS'  DECLARE   aaa ALIAS FOR $1;  BEGIN   IF aaa BETWEEN 1 AND 5 THEN    RETURN 5;   ELSIF aaa BETWEEN 6 AND 10 THEN    RETURN 10;   ELSIF aaa BETWEEN 11 AND 15 THEN    RETURN 15;   END IF;  END;' LANGUAGE 'plpgsql'; ------------------------------------------------------------ 以下のようなSQL構文でこのプロシージャを使用したいと思っています。 ------------------------------------------------------------ select test(フィールド名) from テーブル名; ※「フィールド名」のフィールドにはinteger型のデータが入っています。 ------------------------------------------------------------ が、このSQLを実行すると以下のようなエラーが出ます。(CSE使用) ------------------------------------------------------------ WARNING: Error occurred while executing PL/pgSQL function test WARNING: at END of toplevel PL block WARNING: Error occurred while executing PL/pgSQL function test WARNING: at END of toplevel PL block SQL実行中に以下のエラーが発生しました。 WARNING: at END of toplevel PL block ------------------------------------------------------------ このように、ストアドプロシージャの引数にフィールド名を指定することはできないのでしょうか。 どなたかご教示ください。

  • 手続き言語のPl/pgSQLをcreate languageで登録しようとすると。。

    Vine Linux をベースにPostgresSQL-8.0.1で手続き言語のPl/pgSQLをcreate languageで登録しようとすると、function plpgsql () dose not existとなります。 下記のサイトを見てもいまいちわかりません。 http://shigehiro.hp.infoseek.co.jp/pgsql702-user/sql-createlanguage.htm それで、 create function plpgsql () returns plpgsql as 'usr/local/pgsql/lib/plpgsql.so' language 'c'; と打ち込むと Notice: type "plpgsql" is not yet defined Detail: creating a shell type definition. Error: could not access file "usr/local/pgsql/lib/plpgsql.so": そのようなファイルやディレクトリはありません とでます。linux のコマンドに戻って find file のコマンドを打つと、ファイルは存在します。 どうすればよいのか、御存じの方よろしければ教えていただきたいです。

  • Windows版でPL/Perlが使いたいのですが可能でしょうか?

    WindowsのPostgreSQL8.2.24を使っています。PL/Perlが使いたいのですが、インストール時に、以下のようになります。 データベース・コマンド・エラー: ERROR; could not load library "C:/Program Files/PostgreSQL/8.2/lib/plperl.dll": The specified module could not be found. Windows版でPL/Perlが使いたいのですが可能でしょうか?

  • PL/pgSQLの使い方

    PL/pgSQLについて質問させてください。 以下のような2つのテーブルAとBがあります。 テーブルA: aid | fall0 | fall1 -----+-------+------- 001 | 0 | 0 002 | 0 | 0 テーブルB: bid | aid | fall --------+-----+------ 000001 | 001 | 0 000002 | 001 | 0 000003 | 002 | 0 000004 | 002 | 0 テーブルAとテーブルBの関係は1:nの関係です。 以下のような2つのことがやりたいです。 テーブルAのfall0,fall1,テーブルBのfallはフラグです。 今、テーブルBのaid=001であるすべての行のfallを0から1に変えたとき、 それに対応するテーブルAの行のfall1が0から1にかわる。またテーブルBのaid=001である少なくとも一つの行のfallを0から1に変えたとき、 それに対応するテーブルAの行のfall0が0から1にかわるようなプログラムを作りたいのですが、なかなかうまくいきません。今aid=001のときをやりましたが、aidは任意のときを想定しています。もし、ご存知の方がいらっしゃいましたら教えていただけないでしょうか? よろしくお願いいたします。以下は自分が書いたプログラムです。 drop table b; drop table a; create table A ( aid text primary key, fall0 integer, fall1 integer ); create table B ( bid text primary key, aid text not null references A(aid), fall integer ); insert into A values ('001',0,0); insert into A values ('002',0,0); insert into A values ('003',0,0); insert into B values ('000001','001',0); insert into B values ('000002','001',0); insert into B values ('000003','002',0); insert into B values ('000004','002',0); /* 関数の定義 */ create function tri_test() returns trigger as ' begin declare aid_rec if old.fall=0 and new.fall=1 then update a set fall1=1 where a.aid = select b.aid from b where b.fall = 1); end if; return new; end; ' language 'plpgsql'; /* トリガーの定義 */ create trigger tri_b after update or insert on b for each row execute procedure tri_test(); /* B テーブルへのデータ操作 */ update b set fall=1 where aid='001';

  • RedHatES4にPostgresSQLとPHPを・・・

    edHatES4にostgresSQL7.1.3-5とPHP3.0.18をインストールしようと しています。 [root@** php-3.0.18-i18n-ja-3]# ./configure --with-pgsql=/usr/include/pgsql --with-apxs=/usr/local/apache/bin/apxs --enable-track-vars --enable-versioning --enable-i18n --enable-mbregex でconfigureはできるのですが、makeすると internal_functions.c:59 から include されたファイル中: functions/php3_pgsql.h:46:22: libpq-fe.h: そのようなファイルやディレクトリはあり ません functions/php3_pgsql.h:47:28: libpq/libpq-fs.h: そのようなファイルやディレクトリ はありません In file included from internal_functions.c:59: functions/php3_pgsql.h:89: error: 文法エラー が '*' トークンの前にあります functions/php3_pgsql.h:96: error: 文法エラー が "PGconn" の前にあります functions/php3_pgsql.h:96: 警告: struct や union の最後にセミコロンがありません functions/php3_pgsql.h:98: error: 文法エラー が '}' トークンの前にあります functions/php3_pgsql.h:98: 警告: データ定義が型や記憶クラスを持っていません functions/php3_pgsql.h:101: error: 文法エラー が "PGconn" の前にあります functions/php3_pgsql.h:101: 警告: struct や union の最後にセミコロンがありません functions/php3_pgsql.h:102: 警告: データ定義が型や記憶クラスを持っていません functions/php3_pgsql.h:103: error: 文法エラー が '}' トークンの前にあります functions/php3_pgsql.h:103: 警告: データ定義が型や記憶クラスを持っていません make: *** [internal_functions.o] エラー 1 とでてきます。ネットで調べてあれこれ試しましたが未だ解決しません。 どなたか解る方教えていただけませんでしょうか。よろしくお願いします。