php×postgresでのストアド利用について

このQ&Aのポイント
  • phpとpostgresを組み合わせてストアド(手続き)を呼び出し、結果を取得する方法について教えてください。
  • postgresで作成したストアドをphpから呼び出すためのコードを教えてください。
  • phpでpostgresのストアドを利用する際に必要な手順と注意点を教えてください。
回答を見る
  • ベストアンサー

php×postgresでのストアド利用について

postgresで作成済みの手続き(ストアド)をphpから呼び出し結果を取得したいです。 ■スキーマ CREATE SCHEMA test AUTHORIZATION postgres; ■テーブル CREATE TABLE test.tbl1 ( item1 char(1), item2 int4 ) WITHOUT OIDS; ■ストアド CREATE OR REPLACE FUNCTION test.proc1(IN in_para1 int2, OUT ot_para1 date, OUT ot_para2 date, OUT ot_para3 date) AS $BODY$declare begin select current_date + in_para1 into ot_para1; select tablename from pg_tables into ot_para2; select * from test.tbl1 into ot_para3; end;$BODY$ LANGUAGE 'plpgsql' VOLATILE; ALTER FUNCTION test.proc1(IN in_para1 int2, OUT ot_para1 date, OUT ot_para2 date, OUT ot_para3 date) OWNER TO postgres; サンプル的に下準備をしました。 この後、php側でこのストアドを呼び出すコードを教えて下さい。

  • ngwave
  • お礼率65% (240/366)
  • PHP
  • 回答数2
  • ありがとう数1

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

  • ベストアンサー
回答No.2

MDB2は、結局のところ、PHPの標準関数のラッパーです。 MDB2/Driver/pgsql.php あたりを見てみてください。 普通に、pg_queryを叩いているかと思います。 なので、最終的にpg_queryに直でストアドプロシージャを叩いたときに正しく結果が返ってくるのかを確認していただくのが 最も早いかな、と思います。 それと、すみません、私はストアドプロシージャを使ったことがないので、よくわからないんですが、 http://pear.plus-server.net/package.database.mdb2.intro-function-module.html こちらあたりのマニュアルを閲覧されたんだと思いますが、これで渡せなかった、ってことですよね? これを元に、 MDB2/Driver/Function/pgsql.php の内容を見てみたんですが、こんな感じになってました。 <?php function &executeStoredProc($name, $params = null, $types = null, $result_class = true, $result_wrap_class = false) { $db =& $this->getDBInstance(); if (PEAR::isError($db)) { return $db; } $query = 'SELECT * FROM '.$name; $query .= $params ? '('.implode(', ', $params).')' : '()'; return $db->query($query, $types, $result_class, $result_wrap_class); } ?> 最終的に$queryが、構築完了したSQLなんですが、第二引数の$paramsは、ただ単純にimplodeで展開しただけみたいですね。 ストアドはわかりませんけど、見るからにダメそうな感じですね。 これは、MDB2::queryメソッドに、構築済みのSQLを渡したほうが早い気がしますね。(最初のpg_queryがストアドを通せるかを確認した後に。)

その他の回答 (1)

回答No.1

http://jp2.php.net/manual/ja/pdo.prepared-statements.php PDOを使うと出来るっぽいですね。 例の10番目を観てみてください。

ngwave
質問者

お礼

ありがとうございます。 PDOですか、ストアド自体はそれでいけそうですね。 でも、ちょっと例題のハードルを高く設定しすぎました。 入力パラ1つと、入出力パラにスカラー、アレイ、テーブルと3種類用意してみましたが、ややこしすぎてうまくいっていません。 もう少しシンプルなところから試してみようと思います。 あと、 pear MSB2とかでは出来なさそうですか? マニュアルサイトのFunction Moduleのところに一応例があったのですが、これも出力パラなしのシンプルな例しかなくて。。。

関連するQ&A

  • MySQLのストアドプロシージャについて

    MySQL5.6のストアドプロシージャが返すSELECT結果のフェッチ方法について教えてください。 delimiter $ create procedure sample_proc() begin select * from TEST_TBL; end$ の様なストアドプロシージャがあり、これを他のストアドプロシージャから呼び出して、 ループしながらフェッチしたいのですが、どうすればよいでしょうか。

  • VBでストアドの戻りパラメータを受け取る方法

    VB6.0からADOを利用してSQLServerのストアドプロシージャを呼出し、戻りパラメータを受け取る方法がありましたら教えてください。よろしくお願いします! CREATE PROC TEST ( I_VAL AS INT, O_VAL AS INT OUTPUT ) ~省略~

  • POSTGRESでMYSQLと同じ結果を得る方法

    create table test (a varchar(10), b varchar(10)); insert into test values ('a','a'); insert into test values ('b','b'); insert into test values ('b','c'); insert into test values ('c','d'); select count(*), a, b from test group by a; 上記を実行するとMYSQLでは +----------+------+------+ | count(*) | a | b | +----------+------+------+ | 1 | a | a | | 2 | b | b | | 1 | c | d | +----------+------+------+ という結果になる。 POSTGRESでは以下のエラーになります。 ERROR: column "test.b" must appear in the GROUP BY clause or be used in an aggr egate function select count(*), a, b from test group by a, b; とすると結果が変わってしまいます。 MYSQLと同じ結果をPOSTGRESで得るいい方法はありますか?

  • ストアドプロシージャ作成時のエラーについて

    お世話になっております。 CREATE PROCEDURE AAA (IN param INT) BEGIN SELECT CD, NAME FROM TBL WHERE TBL_KEY = param; END INTEGER型の引数を渡してVARCHAR型のCD、NAMEを取り出す程度のストアドプロシージャを作成しようとすると 1303 - Can't create a PROCEDURE from within another stored routine. なるエラーが表示されて作成ができません。 このエラーの理由についてコメント頂ければ幸いです。

    • ベストアンサー
    • MySQL
  • 多くの選択項目を処理(SELECT)するストアド

    多くの選択項目を処理(SELECT)するストアド とあるデータ検索において、選択項目が10項目以上あり各項目の値をパラメータとして受取り、 該当データを返すストアドを検討しています。 項目が省略された場合は Null値がパラメータとして入ってきて、その項目は条件から除外します。 (全ての項目が省略されたら、全てのレコードが返される)下記の様な方法を考えています・・・ ----------------------------------------------------------------- if @para1 is null  if @para2 is null   if @para3 is null    select * from TBL   else    select * from TBL where koumoku3 = @para3  else   if @para3 is null    select * from TBL where koumoku2 = @para2   else    select * from TBL where koumoku2 = @para2 and koumoku3 = @para3 else  if @para2 is null   if @para3 is null    select * from TBL where koumoku1 = @para1   else    select * from TBL where koumoku1 = @para1 and koumoku3 = @para3  else   if @para3 is null    select * from TBL where koumoku1 = @para1 and koumoku2 = @para2   else    select * from TBL where koumoku1 = @para1 and koumoku2 = @para2 and koumoku3 = @para3 ------------------------------------------------------ 三つでも面倒なのに10項目以上では考えられません。 こんな時どのように作り込めばいいのでしょうか 動的ストアドにして where文自体を編集した物を渡す事も考えましたが、 エクセル出力時のパラメーター長の制限(?)で断念しました。 省略されなかった項目だけでデータを選択したいような事は多々あると思うのですが、 そんな時のオーソドックスは方法はどんな方法なんでしょうか? よろしくお願いします。

  • ストアドプロシージャを実行時のパラメータについて

    はじめましてkou2000と申します。SQLServer2000でストアドプロシージャを作成していますがうまくいきません。 下記のようなことが実際にできるかご教授ください。 CREATE PROCEDURE TEST_PROCEDURE @SYUBETU nvarchar AS SELECT AAAAAAA INTO ##TMP FROM TEST WHERE BBBB IN (@SYUBETU) GO 上記のようなストアドプロシージャを作成しプログラムから実行する際に @SYUBETU = "'1','2','3','4','5'" のような可変の文字列を設定しストアドプロシージャを実行できますでしょうか? よろしくお願いします。

  • Postgresのことで・・・

    質問があります。 test_tbl----------- name varchar(64) number int4 position int4 ------------------- というテーブルがあるとします。 そこにデータを格納したファイルがあります。 データファイル(test.txt)------- '山田',2001,4 '神田',1999,3 '星野',2000,2 '東',2003,1 '鳥越',1999,13(100レコード程あり) ------------------------------ このファイルのデータをtest_tblに格納したいのですがどのようにすればいいのでしょうか? ちなみにデータファイルの形式はtxtでもcsvでも なんでもかまいません。 意味的には insert into test_tbl (name,number,position) values < test.txt とかしたいんですが・・・ 可能でしょうか? ご迷惑をおかけしますが、宜しくお願いいたします。 m(_ _)m -------------------------------

  • ストアドファンクション⇒プロシージャ呼出し失敗する

    参考の通りに、ストアドプロシージャ作成SQL文を発行し、 コマンドライン上からは、以下の通りの結果1となり、 レコードがinsertされます。 <結果1> mysql> call logger('ほげ', 'ホゲ'); Query OK, 1 row affected (0.01 sec) mysql> select * from PROCEDURE_LOG; +--------+--------+---------------------+ | NAME | QUERY | EXECUTE_DATE | +--------+--------+---------------------+ | ほげ | ホゲ | 2014-03-26 10:41:26 | +--------+--------+---------------------+ 1 row in set (0.00 sec) ですが、testというストアドファンクションから呼び出してみましたが、 以下の結果2の通り、失敗します。 <結果2> mysql> select test(); ERROR 1336 (0A000): Dynamic SQL is not allowed in stored function or trigger <test> BEGIN CALL logger('test','1'); RETURN CONCAT('END'); END 現在動作している環境では、どこでエラーが発生したかがわからず、 ロガーの処理をなんとしても実装したいのですが、 いろいろ試してみても、解決できませんでした。 ご教示のほど、よろしくお願いします。 <参考> http://treeapps.hatenablog.com/entry/20120106/p1 <ストアドプロシージャ作成SQL文(logger)> SET NAMES UTF8; delimiter // -- ログ出力 DROP PROCEDURE IF EXISTS logger// CREATE PROCEDURE logger( IN PROCEDURE_NAME TEXT, IN SQL_TEXT TEXT ) BEGIN DECLARE CNT INT; CREATE TABLE IF NOT EXISTS PROCEDURE_LOG ( NAME VARCHAR(64), QUERY TEXT, EXECUTE_DATE TIMESTAMP, KEY IDX1 (NAME, QUERY(64), EXECUTE_DATE) ) ENGINE=MYISAM DEFAULT CHARSET=UTF8; -- 古いログを削除 SELECT COUNT(*) INTO CNT FROM PROCEDURE_LOG; IF CNT >= 1000 THEN DELETE FROM PROCEDURE_LOG LIMIT 1; END IF; -- テーブルにログを記録 SET @sql = CONCAT('INSERT INTO PROCEDURE_LOG VALUES (', QUOTE(PROCEDURE_NAME), ',', QUOTE(SQL_TEXT), ', null)'); PREPARE stmt FROM @sql; EXECUTE stmt; END // delimiter ;

    • ベストアンサー
    • MySQL
  • Postgresのことで・・・

    質問があります。 --test_tbl---------------------- id : integer uid : varchar(32) name : varchar(64) day :date -------------------------------- という上記のテーブルがあるとします。 このテーブルのnameフィールドを varchar(64)からvarchar(120)に変更したいのですが どのようにすればいいでしょうか? Postgresのヴァージョンは7.3.2です。 宜しくお願いいたします。

  • Mysql ストアドファンクション 意図しない結果

    以下の通りストアドファンクションを作成しました。 関数名:fgetLineNew インパラメータ:shop Varchar 8 ※1つだけ。。。 戻り値: Int 11 <ソース> BEGIN DECLARE pline INTEGER(11) DEFAULT NULL; SELECT COUNT(1) INTO pline FROM `hoge` WHERE `SHOP` = shop; IF pline IS NULL THEN SET pline = 10000; END IF; RETURN pline; END 上記のように、作成したストアドファンクションですが、 どんな引数を入れても、戻り値が全ての行(817行)になってしまいます。 以下を参照。 Where区がまったく働いていないのですが、何が原因なのでしょうか。 教えてください。 <ストアドファンクション実行> mysql> select fgetLineNew(1); +----------------+ | fgetLineNew(1) | +----------------+ | 817 | +----------------+ 1 row in set (0.01 sec) mysql> select fgetLineNew(525); +------------------+ | fgetLineNew(525) | +------------------+ | 817 | +------------------+ 1 row in set (0.01 sec) mysql> select fgetLineNew(101); +------------------+ | fgetLineNew(101) | +------------------+ | 817 | +------------------+ 1 row in set (0.00 sec) mysql> select fgetLineNew(525); +------------------+ | fgetLineNew(525) | +------------------+ | 817 | +------------------+ 1 row in set (0.00 sec) mysql> select fgetLineNew('525'); +--------------------+ | fgetLineNew('525') | +--------------------+ | 817 | +--------------------+ 1 row in set (0.01 sec)

    • ベストアンサー
    • MySQL

専門家に質問してみよう