oci_fetch_all

クエリからの複数の行を二次元配列に取得する

説明

int oci_fetch_all(
    resource $statement,
    array &$output,
    int $offset = 0,
    int $limit = -1,
    int $flags = OCI_FETCHSTATEMENT_BY_COLUMN | OCI_ASSOC
)

クエリからの複数の行を二次元配列に取得します。 デフォルトでは、すべての行を返します。

この関数は、クエリを oci_execute で実行した後でのみコールすることができます。

パラメータ

statement

oci_parse で作成して oci_execute で実行した有効な OCI8 ステートメント ID、 あるいは REF CURSOR ステートメント ID。

output

返された行を格納する変数。

LOB 列は文字列として返されます。 Oracle は変換をサポートしています。

データや型の取得についての詳細な情報は oci_fetch_array を参照ください。

offset

結果を取得する際に無視する行数 (デフォルトの値は 0 で、最初の行から開始されます)。

limit

読み込む行数。デフォルトは -1 で、これは offset + 1 番目の行以降のすべての行を意味します。

flags

パラメータ flags は、 配列の構造をあらわし、また連想配列を使うかどうかもあらわします。

oci_fetch_all の配列構造モード
定数 説明
OCI_FETCHSTATEMENT_BY_ROW 配列の配列で、内側の配列はクエリの行単位となります。
OCI_FETCHSTATEMENT_BY_COLUMN 配列の配列で、内側の配列はクエリの列単位となります。 これがデフォルトです。

配列のインデックスには、カラム名あるいは数値を使うことができます。 結果は、どれか一つのモードでだけ返されます。

oci_fetch_all の配列インデックスモード
定数 説明
OCI_NUM 各列の配列に数値添字を使います。
OCI_ASSOC 各カラムを連想配列にします。 これがデフォルトです。

加算演算子 "+" を使って、 配列の構造とインデックス形式の組み合わせを選択します。

Oracle のデフォルトである大文字小文字を区別しないカラム名の場合は、 配列のキーは大文字となります。大文字小文字を区別するカラム名の場合は、 配列のキーの大文字小文字は実際のカラム名と同じになります。 var_dumpoutput を確認し、大文字小文字を適切に指定するようにしましょう。

同じ名前のカラムが複数あるクエリでは、カラムの別名を使わなければなりません。 そうしないと、連想配列にあらわれるのはその中の一つのカラムだけとなってしまいます。

戻り値

output の行数を返します。 これは 0 以上の値となります。

例1 oci_fetch_all の例

<?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 POSTAL_CODE, CITY FROM locations WHERE ROWNUM < 3');
oci_execute($stid);

$nrows = oci_fetch_all($stid, $res);

echo "$nrows rows fetched<br>\n";
var_dump($res);

// var_dump 出力は
//    2 rows fetched
//    array(2) {
//      ["POSTAL_CODE"]=>
//      array(2) {
//        [0]=>
//        string(6) "00989x"
//        [1]=>
//        string(6) "10934x"
//      }
//      ["CITY"]=>
//      array(2) {
//        [0]=>
//        string(4) "Roma"
//        [1]=>
//        string(6) "Venice"
//      }
//    }

// 結果を見やすく表示します
echo "<table border='1'>\n";
foreach ($res as $col) {
    echo "<tr>\n";
    foreach ($col as $item) {
        echo "    <td>".($item !== null ? htmlentities($item, ENT_QUOTES) : "")."</td>\n";
    }
    echo "</tr>\n";
}
echo "</table>\n";

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

?>

例2 oci_fetch_allOCI_FETCHSTATEMENT_BY_ROW を使う例

<?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 POSTAL_CODE, CITY FROM locations WHERE ROWNUM < 3');
oci_execute($stid);

$nrows = oci_fetch_all($stid, $res, null, null, OCI_FETCHSTATEMENT_BY_ROW);

echo "$nrows rows fetched<br>\n";
var_dump($res);

// 出力は
//    2 rows fetched
//    array(2) {
//      [0]=>
//      array(2) {
//        ["POSTAL_CODE"]=>
//        string(6) "00989x"
//        ["CITY"]=>
//        string(4) "Roma"
//      }
//      [1]=>
//      array(2) {
//        ["POSTAL_CODE"]=>
//        string(6) "10934x"
//        ["CITY"]=>
//        string(6) "Venice"
//      }
//    }

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

?>

例3 oci_fetch_allOCI_NUM を使う例

<?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 POSTAL_CODE, CITY FROM locations WHERE ROWNUM < 3');
oci_execute($stid);

$nrows = oci_fetch_all($stid, $res, null, null, OCI_FETCHSTATEMENT_BY_ROW + OCI_NUM);

echo "$nrows rows fetched<br>\n";
var_dump($res);

// 出力は
//    2 rows fetched
//    array(2) {
//      [0]=>
//      array(2) {
//        [0]=>
//        string(6) "00989x"
//        [1]=>
//        string(4) "Roma"
//      }
//      [1]=>
//      array(2) {
//        [0]=>
//        string(6) "10934x"
//        [1]=>
//        string(6) "Venice"
//      }
//    }

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

?>

注意

注意:

offset を使うのは、非常に非効率的です。 読み飛ばす行もすべて PHP がデータベースから受け取る結果セットに含まれ、 そのあとで読み飛ばす部分が捨てられます。 それよりは、SQL を使って取得開始位置と取得範囲をはじめから指定した方がより効率的です。 oci_fetch_array の例を参照ください。

注意:

大量の行を返すクエリでは、oci_fetch_array のような単一行の取得関数を使ったほうがメモリを浪費せずに済みます。

注意:

大量の行を返すクエリの場合、 oci8.default_prefetch を増やすか oci_set_prefetch を使えばパフォーマンスが劇的に向上します。

注意:

Oracle Database 12c の暗黙の結果セットからの行は返しません。 代わりに oci_fetch_array を使いましょう。

参考

  • oci_fetch
  • oci_fetch_array
  • oci_fetch_assoc
  • oci_fetch_object
  • oci_fetch_row
  • oci_set_prefetch