関数・クラス解説
oci_fetch_array
version:PHP 5, PHP 7, PECL OCI8 >= 1.1.0 (公式)クエリの次の行を連想配列あるいは数値添字配列で返す
公式リファレンス
書式
oci_fetch_array ( resource $statement [, int $mode ] ) : array
説明
クエリから、結果セットの次の行を含む配列を返します。 配列の各エントリが行の各カラムをあらわします。 この関数の典型的な使い方は、ループの中で FALSE を返すまでコールすることです。 FALSE は、もう行がないことを意味します。
statement が Oracle Database 12c の暗黙の結果セットを返す PL/SQL ブロックである場合、 すべてのセットからの行を続けて取得します。 statement が oci_get_implicit_resultset() の戻す値である場合、 ひとつの子クエリーからの行のサブセットだけを返します。
OCI8 拡張モジュールによるデータ型マッピングの詳細については、ドライバがサポートするデータ型 を参照ください。
パラメータ
- statement
- oci_parse() で作成してoci_execute() で実行した有効な OCI8 ステートメント ID、あるいは REFCURSOR ステートメント ID。 oci_get_implicit_resultset() が戻すステートメント ID も指定できます。
- mode
- オプションの第2引数は、次の定数の組み合わせが可能です。
oci_fetch_array() のモード 定数 説明 OCI_BOTH 連想配列と配列の両方を返します。 これは OCI_ASSOC + OCI_NUM と同等で、 デフォルトの動作です。 OCI_ASSOC 連想配列を返します。 OCI_NUM 数値添字配列を返します。 OCI_RETURN_NULLS NULL フィールドの要素も作成します。この要素の値は PHP の NULL となります。 OCI_RETURN_LOBS LOB ディスクリプタではなく LOB の中身を返します。
返値
連想配列や数値添字配列を返します。 statement にもう行がない場合は FALSE を返します。 デフォルトでは、LOB カラムは LOB ディスクリプタを返します。 DATE カラムは、現行のデータフォーマットにフォーマットされた 文字列として返されます。既定のフォーマットは NLS_LANG のような Oracle 環境変数で変更したり、またはあらかじめ ALTER SESSION SET NLS_DATE_FORMAT コマンドを実行して変更します。 Oracle のデフォルトでは、大文字小文字を区別しないカラム名はすべて大文字となり、 結果の連想配列のインデックスも大文字になります。 大文字小文字を区別するカラム名は、配列のインデックスもそれと同じになります。 結果の配列を var_dump() すれば、 各クエリの大文字小文字を確かめることができます。 テーブル名は配列のインデックスには含まれません。 もし同じ名前の別カラムを複数取得するクエリを実行する場合は、 OCI_NUM を使うか、あるいはカラムのエイリアスを指定して名前の一意性を保ちましょう。 例 7 を参照ください。そうしなければ、PHP からはひとつのカラムだけしか見えなくなります。
注意
注意: 大文字小文字を区別せずにつくった Oracle のカラムでは、 連想配列のインデックスはすべて大文字となることに注意しましょう。
注意: 大量の行を返すクエリの場合、oci8.default_prefetchを増やすかoci_set_prefetch() を使えばパフォーマンスが劇的に向上します。
注意: oci_fetch_array() は ほんの少しだけ oci_fetch_assoc() や oci_fetch_row() より低速ですが、 ずっと柔軟性があります。
サンプル
例1 oci_fetch_array() での OCI_BOTH の使用例
$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 department_id, department_name FROM departments');
oci_execute($stid);
while (($row = oci_fetch_array($stid, OCI_BOTH)) != false) {
// 連想配列の指標として大文字のカラム名を使用します
echo $row[0] . " and " . $row['DEPARTMENT_ID'] . " are the same
\n";
echo $row[1] . " and " . $row['DEPARTMENT_NAME'] . " are the same
\n";
}
oci_free_statement($stid);
oci_close($conn);
例2 oci_fetch_array() での OCI_NUM の使用例
/*
実行する前にテーブルを作成します。
CREATE TABLE mytab (id NUMBER, description CLOB);
INSERT INTO mytab (id, description) values (1, 'A very long string');
COMMIT;
*/
$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 id, description FROM mytab');
oci_execute($stid);
while (($row = oci_fetch_array($stid, OCI_NUM)) != false) {
echo $row[0] . "
\n";
echo $row[1]->read(11) . "
\n"; // DESCRIPTION から最初の 11 バイトを出力します
}
// 出力です。
// 1
// A very long
oci_free_statement($stid);
oci_close($conn);
例3 oci_fetch_array() での OCI_ASSOC の使用例
/*
実行する前にテーブルを作成します。
CREATE TABLE mytab (id NUMBER, description CLOB);
INSERT INTO mytab (id, description) values (1, 'A very long string');
COMMIT;
*/
$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 id, description FROM mytab');
oci_execute($stid);
while (($row = oci_fetch_array($stid, OCI_ASSOC)) != false) {
echo $row['ID'] . "
\n";
echo $row['DESCRIPTION']->read(11) . "
\n"; // DESCRIPTION から最初の 11 バイトを出力します
}
// 出力です。
// 1
// A very long
oci_free_statement($stid);
oci_close($conn);
例4 oci_fetch_array() での OCI_RETURN_NULLS の使用例
$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 1, null FROM dual');
oci_execute($stid);
while (($row = oci_fetch_array ($stid, OCI_ASSOC)) != false) { // NULL を無視
var_dump($row);
}
/*
上記のコードの出力です。
array(1) {
[1]=>
string(1) "1"
}
*/
$stid = oci_parse($conn, 'SELECT 1, null FROM dual');
oci_execute($stid);
while (($row = oci_fetch_array ($stid, OCI_ASSOC+OCI_RETURN_NULLS)) != false) { // NULL をフェッチ
var_dump($row);
}
/*
上記のコードの出力です。
array(2) {
[1]=>
string(1) "1"
["NULL"]=>
NULL
}
*/
例5 oci_fetch_array() での OCI_RETURN_LOBS の使用例
/*
実行する前にテーブルを作成します。
CREATE TABLE mytab (id NUMBER, description CLOB);
INSERT INTO mytab (id, description) values (1, 'A very long string');
COMMIT;
*/
$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 id, description FROM mytab');
oci_execute($stid);
while (($row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_LOBS)) != false) {
echo $row['ID'] . "
\n";
echo $row['DESCRIPTION'] . "
\n"; // DESCRIPTION の全てが含まれます
// ループ内で、大きなサイズの変数を解放してから次のフェッチに進めます。
// これで、PHP のピークメモリ利用量を抑えます。
unset($row);
}
// 出力です。
// 1
// A very long string
oci_free_statement($stid);
oci_close($conn);
例6 oci_fetch_array() での文字の大小を区別するカラムの使用例
/*
実行する前にテーブルを作成します。
CREATE TABLE mytab ("Name" VARCHAR2(20), city VARCHAR2(20));
INSERT INTO mytab ("Name", city) values ('Chris', 'Melbourne');
COMMIT;
*/
$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 mytab');
oci_execute($stid);
$row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS);
// 'Name' は文字の大小を区別するカラムとして作成されたので、配列の指標として
// 同一のケースを使用します。しかしながら、文字の大小を区別しないカラムの
// 指標としては、大文字の 'CITY' を使わなければいけません。
print $row['Name'] . "
\n"; // Chris を出力
print $row['CITY'] . "
\n"; // Melbourne を出力
oci_free_statement($stid);
oci_close($conn);
例7 oci_fetch_array() での同じ名前のカラムの使用例
/*
実行する前にテーブルを作成します。
CREATE TABLE mycity (id NUMBER, name VARCHAR2(20));
INSERT INTO mycity (id, name) values (1, 'Melbourne');
CREATE TABLE mycountry (id NUMBER, name VARCHAR2(20));
INSERT INTO mycountry (id, name) values (1, 'Australia');
COMMIT;
*/
$conn = oci_connect('hr', 'welcome', 'localhost/XE');
if (!$conn) {
$e = oci_error();
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}
$sql = 'SELECT mycity.name, mycountry.name
FROM mycity, mycountry
WHERE mycity.id = mycountry.id';
$stid = oci_parse($conn, $sql);
oci_execute($stid);
$row = oci_fetch_array($stid, OCI_ASSOC);
var_dump($row);
// 出力には "NAME" 項目一つだけが含まれます。
// array(1) {
// ["NAME"]=>
// string(9) "Australia"
// }
// 度重なるカラム名を照会するには、 "AS ctnm" のような SQL カラムのエイリアスを使います。
$sql = 'SELECT mycity.name AS ctnm, mycountry.name
FROM mycity, mycountry
WHERE mycity.id = mycountry.id';
$stid = oci_parse($conn, $sql);
oci_execute($stid);
$row = oci_fetch_array($stid, OCI_ASSOC);
var_dump($row);
// これで出力には選択したカラムが両方含まれます。
// array(2) {
// ["CTNM"]=>
// string(9) "Melbourne"
// ["NAME"]=>
// string(9) "Australia"
// }
oci_free_statement($stid);
oci_close($conn);
例8 oci_fetch_array() での DATE カラムの使用例
$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, "ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD'");
oci_execute($stid);
$stid = oci_parse($conn, 'SELECT hire_date FROM employees WHERE employee_id = 188');
oci_execute($stid);
$row = oci_fetch_array($stid, OCI_ASSOC);
echo $row['HIRE_DATE'] . "
\n"; // 1997-06-14 を出力
oci_free_statement($stid);
oci_close($conn);
例9 oci_fetch_array() での REF CURSOR の使用例
/*
下記のようにして PL/SQL ストアド・プロシジャーを作成します。
CREATE OR REPLACE PROCEDURE myproc(p1 OUT SYS_REFCURSOR) AS
BEGIN
OPEN p1 FOR SELECT * FROM all_objects WHERE ROWNUM < 5000;
END;
*/
$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, 'BEGIN myproc(:rc); END;');
$refcur = oci_new_cursor($conn);
oci_bind_by_name($stid, ':rc', $refcur, -1, OCI_B_CURSOR);
oci_execute($stid);
// 返された REF CURSOR を実行して、ステートメント識別子のようにそこからフェッチします
oci_execute($refcur);
echo "\n";
while (($row = oci_fetch_array($refcur, OCI_ASSOC+OCI_RETURN_NULLS)) != false) {
echo "\n";
foreach ($row as $item) {
echo " ".($item !== null ? htmlentities($item, ENT_QUOTES) : " ")." \n";
}
echo " \n";
}
echo "
\n";
oci_free_statement($refcur);
oci_free_statement($stid);
oci_close($conn);
例10 oci_fetch_array() での LIMIT 風のクエリによるページング
$conn = oci_connect('hr', 'welcome', 'localhost/XE');
if (!$conn) {
$e = oci_error();
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}
// データベースのバージョンを調べます
preg_match('/Release ([0-9]+)\./', oci_server_version($conn), $matches);
$oracleversion = $matches[1];
// これがページングさせたいクエリーです
$sql = 'SELECT city, postal_code FROM locations ORDER BY city';
if ($oracleversion >= 12) {
// Oracle 12c の OFFSET / FETCH NEXT 構文を使います
$sql = $sql . ' OFFSET :offset ROWS FETCH NEXT :numrows ROWS ONLY';
} else {
// 古いバージョンの Oracle では、ネストしたクエリーを作り、$sql から
// 行のサブセットを選択する必要があります。あるいは、開発時に SQL 文が
// わかっているのなら、この方法ではなく row_number() 関数を使うことを
// 検討しましょう。運用環境では、文字列の連結にともなう SQL インジェクション
// の問題に気をつけましょう。
$sql = "SELECT * FROM (SELECT a.*, ROWNUM AS my_rnum
FROM ($sql) a
WHERE ROWNUM <= :offset + :numrows)
WHERE my_rnum > :offset";
}
$offset = 0; // この行数だけ飛ばす
$numrows = 5; // 5 行を返す
$stid = oci_parse($conn, $sql);
oci_bind_by_name($stid, ':numrows', $numrows);
oci_bind_by_name($stid, ':offset', $offset);
oci_execute($stid);
while (($row = oci_fetch_array($stid, OCI_ASSOC + OCI_RETURN_NULLS)) != false) {
echo $row['CITY'] . " " . $row['POSTAL_CODE'] . "
\n";
}
// 出力は
// Beijing 190518
// Bern 3095
// Bombay 490231
// Geneva 1730
// Hiroshima 6823
oci_free_statement($stid);
oci_close($conn);
例11 oci_fetch_array() で Oracle Database 12c の暗黙の結果セットを使う例
$conn = oci_connect('hr', 'welcome', 'localhost/pdborcl');
if (!$conn) {
$e = oci_error();
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}
// OCI8 2.0 と Oracle Database 12c が必要です。
// oci_get_implicit_resultset() も参照ください。
$sql = 'DECLARE
c1 SYS_REFCURSOR;
BEGIN
OPEN c1 FOR SELECT city, postal_code FROM locations WHERE ROWNUM < 4 ORDER BY city;
DBMS_SQL.RETURN_RESULT(c1);
OPEN c1 FOR SELECT country_id FROM locations WHERE ROWNUM < 4 ORDER BY city;
DBMS_SQL.RETURN_RESULT(c1);
END;';
$stid = oci_parse($conn, $sql);
oci_execute($stid);
// 注意: oci_fetch_all と oci_fetch() は、この場合は使えません
echo "\n";
while (($row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS)) != false) {
echo "\n";
foreach ($row as $item) {
echo " ".($item!==null?htmlentities($item, ENT_QUOTES|ENT_SUBSTITUTE):" ")." \n";
}
echo " \n";
}
echo "
\n";
// 出力です。
// Beijing 190518
// Bern 3095
// Bombay 490231
// CN
// CH
// IN
oci_free_statement($stid);
oci_close($conn);
参考
ワード検索
※入力キーワードが、関数名・説明文・タグに含まれるものを検索関数名アルファベット別
最終更新一覧
●stristr
大文字小文字を区別せず文字列を検索し、ヒット箇所以降(あるいは以前)の文字列を返却
●stripslashes
バックスラッシュでエスケープされた文字列から、バックスラッシュを取り除く
●stripos
大文字小文字を区別せずに文字列が最初に現れる位置を取得する
●stripcslashes
addcslashes() でクォートされた文字列をアンクォートする
●strip_tags
文字列から HTML と PHP のタグを除去して返却
●strcspn
指定した文字が最初に現れる位置を調べる
●strcoll
ロケールに基づいて2つの文字列を比較し同じか(あるいは大小)を判定する
●strcmp
2つの文字列を比較し同じか(あるいは大小)を判定する
●strchr
strstr() のエイリアス
●strcasecmp
2つの文字列を比較(大文字小文字を区別せず同じとみなす)
カテゴリー一覧
PHP の振る舞いの変更
音声フォーマットの操作
認証サービス
コマンドライン関連
圧縮およびアーカイブ
暗号
データベース関連
日付および時刻関連
ファイルシステム
自然言語および文字エンコーディング
画像処理および作成
メール関連
数学
テキスト以外の MIME 型
プロセス制御
その他の基本モジュール
その他のサービス
検索エンジン用の拡張モジュール
サーバー固有のモジュール
セッション関連
テキスト処理
変数・データ型関連
ウェブサービス
Windows 用のモジュール
XML 操作
GUI用の拡張モジュール