Do You PHP?    
Search Engine Optimization  php5 powerd  Valid XHTML 1.0!  Valid CSS!  このサイトのはてなブックマーク数 



last updated
2006/10/31

counter hits
since 1999/11/06


ストアドプロシージャ・ファンクションの実行

alertOracle関数(Ora_XXXX関数)は推奨されない関数となっています。PDO関数が使えない・使わない場合は、OCI8関数(現在のOracle関数)を使いましょう。

PHPからストアドプロシージャ・ファンクションを呼び出す方法は、SQL*Plusで無名プロシージャを実行するときの要領でそのまま実行すればOKです。例として、以下のようなテーブル、プロシージャを考えてみます。

●テスト用テーブル定義
CREATE TABLE test(
    col1 VARCHAR2(20),
    col2 VARCHAR2(20)
);
  
●プロシージャ定義
CREATE OR REPLACE PROCEDURE p_test
IS
BEGIN
    INSERT INTO test
    VALUES ('test1','test2');
    COMMIT;
EXCEPTION
    WHEN OTHERS THEN
        ROLLBACK;
END;
  

そして以下のPHPスクリプトで、ストアドプロシージャ「p_test」を実行し、テーブル「test」にデータをINSERTしています。

●PHPスクリプト

<?php
    /* 無名プロシージャの定義 */
    $sql = "declare begin p_test; end;";

    $conn = Ora_Logon("scott@orcl", "tiger");
    $cursor = Ora_Open($conn);

    Ora_Parse($cursor, $sql);
    $ncols = Ora_Exec($cursor);

    Ora_Close($cursor);
    Ora_Logoff($conn);
?>

また、ストアド内のOracle変数をPHP変数とbindすることで、PHP側で参照できるようになります。例えば、以下のように無名プロシージャからストアドファンクションを呼びだし、結果を取り出す状況を考えてみます。

●プロシージャ定義
DECLARE
    ret INTEGER := 0;
BEGIN
    /* 最終的に、PHPでこのretの値を取り出す */
    :ret := test(1, 2);
END;
  
●ファンクション定義
CREATE OR REPLACE FUNCTION test(
    a IN INTEGER,
    b IN INTEGER
) RETURN INTEGER
IS
BEGIN
    RETURN (a + b);
END;
  

まず、Oracle関数の場合、Ora_Bind 関数を使用して、戻り値を取得します。この時、PHP変数はglobal変数である必要があるようです。以下のようなコードで、global 宣言をせずにfunction 内で $return_value を宣言しても、Can't find variable for parameter in ...というエラーが出ます。

●PHPスクリプト

<?php
    function ad(){
        /**
         * GLOBAL変数を参照する
         */
        global $return_value;

        $conn = Ora_Logon( "scott@orcl", "tiger" );
        $cursor = Ora_Open($conn);

        $sql  = "declare ";
        $sql .= "ret integer default 0; ";
        $sql .= "begin ";
        $sql .= ":ret := test(1,2); ";
        $sql .= "end;";

        Ora_Parse($cursor, $sql);
        Ora_Bind($cursor, "return_value", ":ret", 2, ORA_BIND_OUT);
        Ora_Exec( $cursor );

        echo "return_value=$return_value";

        Ora_Close($cursor);
        Ora_Logoff($conn);
        return $return_value;
    }

    echo "ret=".ad()."<BR>";
?>

次に、OCI8関数の場合、OCIBindByName 関数を使用します。なお、BIND する Oracle 変数は、大文字で記述する必要があるので、注意しましょう。また、LOB・ROWID・BFILEなどのデータ型を BIND する場合、OCINewDescriptor 関数を使用して PHP 変数を定義しておく必要があります

●PHPスクリプト

<?php
    $conn = OCILogon( "scott", "tiger", "orcl");

    $sql  = "begin ";
    $sql .= ":ret := test(1,2); ";
    $sql .= "end;";

    $sql = OCIParse($conn, $sql);

    /**
     * BINDするOracle変数は、大文字で記述する
     */
    OCIBindByName($sql,  ":RET" , &$ret, 2);

    OCIExecute($sql, OCI_DEFAULT );

    echo "ret=$ret";

    OCIFreeStatement($sql);
    OCILogoff($conn);
?>



About This Site |  Privacy Policy |  Contact
Copyright © 1999 - 2006 by Hideyuki SHIMOOKA all rights reserved.