OCI8
PHP Manual

これらの例では HR として接続しています。 これは、Oracle データベースに付属するサンプルのスキーマ "Human Resources" 用のユーザーです。このユーザーを使うには、 ユーザーのロックを解除してパスワードをリセットしなければなりません。

このサンプルでは、ローカルマシン上にある XE データベースに接続しています。それぞれの環境にあわせて 接続文字列を変更してください。

例1 基本的なクエリ

ここでは、クエリの結果を表示させます。OCI8 のステートメントは 準備-実行-フェッチ という手順をとります。

<?php

$conn 
oci_connect('hr''welcome''localhost/XE');
if (!
$conn) {
    
$e oci_error();
    
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

// 文を準備します
$stid oci_parse($conn'SELECT * FROM departments');
if (!
$stid) {
    
$e oci_error($conn);
    
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

// クエリを実行します
$r oci_execute($stid);
if (!
$r) {
    
$e oci_error($stid);
    
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

// クエリの結果を取得します
print "<table border='1'>\n";
while (
$row oci_fetch_array($stidOCI_ASSOC+OCI_RETURN_NULLS)) {
    print 
"<tr>\n";
    foreach (
$row as $item) {
        print 
"    <td>" . ($item !== null htmlentities($itemENT_QUOTES) : "&nbsp;") . "</td>\n";
    }
    print 
"</tr>\n";
}
print 
"</table>\n";

oci_free_statement($stid);
oci_close($conn);

?>

例2 バインド変数を用いた挿入

バインド変数を使うと、実行コンテキストをキャッシュして再利用できるので パフォーマンスが向上します。また、バインド変数を使うと SQL インジェクション対策にもなって安全性が向上します。

<?php

// 実行前に表を作成します
//   CREATE TABLE MYTABLE (mid NUMBER, myd VARCHAR2(20));

$conn oci_connect('hr''welcome''localhost/XE');
if (!
$conn) {
    
$e oci_error();
    
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

$stid oci_parse($conn'INSERT INTO MYTABLE (mid, myd) VALUES(:myid, :mydata)');

$id 60;
$data 'Some data';

oci_bind_by_name($stid':myid'$id);
oci_bind_by_name($stid':mydata'$data);

$r oci_execute($stid);  // 実行してコミットします

if ($r) {
    print 
"One row inserted";
}

oci_free_statement($stid);
oci_close($conn);

?>

例3 クエリの WHERE 句でのバインド

単一のスカラー値のバインドの例です。

<?php

$conn 
oci_connect("hr""hrpwd""localhost/XE");
if (!
$conn) {
    
$m oci_error();
    
trigger_error(htmlentities($m['message']), E_USER_ERROR);
}

$sql 'SELECT last_name FROM employees WHERE department_id = :didbv ORDER BY last_name';
$stid oci_parse($conn$sql);
$didbv 60;
oci_bind_by_name($stid':didbv'$didbv);
oci_execute($stid);
while ((
$row oci_fetch_array($stidOCI_ASSOC)) != false) {
    echo 
$row['LAST_NAME'] ."<br>\n";
}

// 出力は
//    Austin
//    Ernst
//    Hunold
//    Lorentz
//    Pataballa

oci_free_statement($stid);
oci_close($conn);

?>

例4 CLOB カラムにデータを挿入する

巨大なデータに対しては、バイナリラージオブジェクト (BLOB) あるいはキャラクタラージオブジェクト (CLOB) 型を使います。 この例では CLOB を使います。

<?php

// 実行前に表を作成します
//     CREATE TABLE MYTABLE (mykey NUMBER, myclob CLOB);

$conn oci_connect('hr''welcome''localhost/XE');
if (!
$conn) {
    
$e oci_error();
    
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

$mykey 12343;  // この例で用いる任意のキー

$sql "INSERT INTO mytable (mykey, myclob)
        VALUES (:mykey, EMPTY_CLOB())
        RETURNING myclob INTO :myclob"
;

$stid oci_parse($conn$sql);
$clob oci_new_descriptor($connOCI_D_LOB);
oci_bind_by_name($stid":mykey"$mykey5);
oci_bind_by_name($stid":myclob"$clob, -1OCI_B_CLOB);
oci_execute($stidOCI_NO_AUTO_COMMIT); // PHP <= 5.3.1 では OCI_DEFAULT を使います
$clob->save("A very long string");

oci_commit($conn);

// CLOB データを取得します

$query 'SELECT myclob FROM mytable WHERE mykey = :mykey';

$stid oci_parse ($conn$query);
oci_bind_by_name($stid":mykey"$mykey5);
oci_execute($stid);

print 
'<table border="1">';
while (
$row oci_fetch_array($stidOCI_ASSOC+OCI_RETURN_LOBS)) {
    print 
'<tr><td>'.$row['MYCLOB'].'</td></tr>';
    
// ループ内で、大きなサイズの変数を解放してから次のフェッチに進めます。
    // これで、PHP のピークメモリ利用量を抑えます。
    
unset($row);
}
print 
'</table>';

?>

例5 PL/SQL ストアドファンクションの使用

返り値に変数をバインドしなければなりません。 オプションで PL/SQL 関数の引数がある場合はそこにも変数をバインドしなければなりません。

<?php

/*
  PHP プログラムを実行する前に、ストアドファンクションを
  SQL*Plus あるいは SQL Developer で作成します

  CREATE OR REPLACE FUNCTION myfunc(p IN NUMBER) RETURN NUMBER AS
  BEGIN
      RETURN p * 3;
  END;

*/

$conn oci_connect('hr''welcome''localhost/XE');
if (!
$conn) {
    
$e oci_error();
    
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

$p 8;

$stid oci_parse($conn'begin :r := myfunc(:p); end;');
oci_bind_by_name($stid':p'$p);
oci_bind_by_name($stid':r'$r40);

oci_execute($stid);

print 
"$r\n";   // 24 と表示します

oci_free_statement($stid);
oci_close($conn);

?>

例6 PL/SQL ストアドプロシージャの使用

ストアドプロシージャでは、すべての引数に変数をバインドしなければなりません。

<?php

/*
  PHP プログラムを実行する前に、ストアドプロシージャを
  SQL*Plus あるいは SQL Developer で作成します

  CREATE OR REPLACE PROCEDURE myproc(p1 IN NUMBER, p2 OUT NUMBER) AS
  BEGIN
      p2 := p1 * 2;
  END;

*/

$conn oci_connect('hr''welcome''localhost/XE');
if (!
$conn) {
    
$e oci_error();
    
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

$p1 8;

$stid oci_parse($conn'begin myproc(:p1, :p2); end;');
oci_bind_by_name($stid':p1'$p1);
oci_bind_by_name($stid':p2'$p240);

oci_execute($stid);

print 
"$p2\n";   // 16 と表示します

oci_free_statement($stid);
oci_close($conn);

?>

例7 REF CURSOR を返す PL/SQL ファンクションのコール

クエリが返す値が REF CURSOR となり、そこから値を取得することができます。

<?php
/*
  このような PL/SQL ストアドファンクションを作成します

  CREATE OR REPLACE FUNCTION myfunc(p1 IN NUMBER) RETURN SYS_REFCURSOR AS
      rc SYS_REFCURSOR;
  BEGIN
      OPEN rc FOR SELECT city FROM locations WHERE ROWNUM < p1;
      RETURN rc;
  END;
*/

$conn oci_connect('hr''welcome''localhost/XE');

$stid oci_parse($conn'SELECT myfunc(5) AS mfrc FROM dual');
oci_execute($stid);

echo 
"<table border='1'>\n";
while ((
$row oci_fetch_array($stidOCI_ASSOC))) {
    echo 
"<tr>\n";
    
$rc $row['MFRC'];
    
oci_execute($rc);  // returned column value from the query is a ref cursor
    
while (($rc_row oci_fetch_array($rcOCI_ASSOC))) {   
        echo 
"    <td>" $rc_row['CITY'] . "</td>\n";
    }
    
oci_free_statement($rc);
    echo 
"</tr>\n";
}
echo 
"</table>\n";

// 出力は
//   Beijing
//   Bern
//   Bombay
//   Geneva

oci_free_statement($stid);
oci_close($conn);

?>

OCI8
PHP Manual