PHP/OCI関数でストアドプロシージャを呼ぶ

 PHPのOCI8関数を使ってOracleデータベースにアクセスする際、 通常のSQL文だけでなく、OracleのPL/SQLブロック(DECLARE〜BEGIN〜END) をOCIParse関数に渡して実行させることもできます。

<?php
function fin_exit(){
  print <<<FOOTER
<a href="input_form.html">入力フォームに戻る</a><br></body></html>
FOOTER;
  exit;
}

if(($con = OCILogon("username", "password", "SID")) == 0){
?>
  <h2>おおっと</h2>Oracleサーバに接続できません。<br>
<?php
  fin_exit();
}
$s = <<<SQL
  declare
  begin
    stored_proc($empno, '$kanji_name', '$mail_address',
                :process_code, :ora);
  end;
SQL;
$process_code = 0;
$ora = 0;
$stmt = OCIParse($con, $s);
OCIBindByName($stmt, ":process_code", &$process_code, -1);
OCIBindByName($stmt, ":ora", &$ora, -1);

$r = OCIExecute($stmt, OCI_DEFAULT);

if($ora != 0){
?>
  <h1><font color="#600000">おおっと</font></h1>
  プロシージャの実行エラーです:[<?= $ora ?>]<br>
<?php
  OCIRollback($con);
}
else{
?>
  <h1><font color="#600000">実行しました。</font></h1>
<?php
  OCICommit($con);
}
OCIFreeStatement($stmt);
OCILogoff($con);
fin_exit();
?>

 このように、ストアドプロシージャを呼びたい場合には、PL/SQLブロックの中で呼びます。 (PL/SQL変数は特に必要なければDECLARE節で定義する必要はありません。 PHP世界とのデータのやりとりはプレースホルダ変数を使えば可能です) プロシージャへの入力引数は上の例の通りベタ書きで渡してもよいですし、 OCIBindByName関数を使ってもよいでしょう。 出力引数の値を受け取るには、 出力引数の箇所にプレースホルダ変数を指定し、 OCIBindByName関数を使ってPHP変数にバインドします。 ただし、BOOLEAN型の出力引数の値をOCIBindByName関数で PHP変数にバインドしてOCIExecuteを実行すると、 ORA-6560エラー(プロシージャ引数のデータ型または数が異なります) が発生してしまうようです
また、マニュアルには明記されていませんが、 OCICommitせずにOCILogOffすると、それまでの変更はコミットではなくロールバックされてしまうようです。 この挙動はJDBCなどに慣れているとちょっとぎょっとするので、要注意、ですね。 明示的にコミットするクセをつける必要があります。

★PHP 5以降は、OCI関連の関数名の多くが変更になっていて、 ここで使っている関数名はまだ使えますが非推奨の扱いになっています。 今後適宜読み替えて下さいね。

Open Source Web Architecture Top

(first uploaded 2002/01/02 last updated 2005/07/23, URANO398)

テレワークならECナビ Yahoo 楽天 LINEがデータ消費ゼロで月額500円〜!
無料ホームページ 無料のクレジットカード 海外格安航空券 海外旅行保険が無料! 海外ホテル