例
これらの例では 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($stid, OCI_ASSOC+OCI_RETURN_NULLS)) { print "<tr>\n"; foreach ($row as $item) { print " <td>" . ($item !== null ? htmlentities($item, ENT_QUOTES) : " ") . "</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($stid, OCI_ASSOC)) != false) { echo $row['LAST_NAME'] ."<br>\n";}// 出力は// Austin// Ernst// Hunold// Lorentz// Pataballaoci_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($conn, OCI_D_LOB);oci_bind_by_name($stid, ":mykey", $mykey, 5);oci_bind_by_name($stid, ":myclob", $clob, -1, OCI_B_CLOB);oci_execute($stid, OCI_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", $mykey, 5);oci_execute($stid);print '<table border="1">';while ($row = oci_fetch_array($stid, OCI_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', $r, 40);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', $p2, 40);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($stid, OCI_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($rc, OCI_ASSOC))) { echo " <td>" . $rc_row['CITY'] . "</td>\n"; } oci_free_statement($rc); echo "</tr>\n";}echo "</table>\n";// 出力は// Beijing// Bern// Bombay// Genevaoci_free_statement($stid);oci_close($conn);?>