oci_fetch_array

(PHP 5, PHP 7, PECL OCI8 >= 1.1.0)

oci_fetch_arrayВозвращает следующую строку из результата запроса в виде ассоциативного или нумерованного массива

Описание

array oci_fetch_array ( resource $statement [, int $mode ] )

Возвращает массив, содержащий следующую строку результата запроса. Каждый элемент массива соответствует одному полю из строки. Эта функция обычно вызывается в цикле, пока она не вернет FALSE, который указывает на отсутствие последующих строк.

Если statement соответствует PL/SQL блоку, возвращаемому Oracle Database 12c Implicit Result Sets, тогда будут последовательно извлечены ряды из всех наборов. Если statement возвращается из oci_get_implicit_resultset(), тогда вернется только часть рядов для одного дочернего запроса.

За подробностями по операции отображения типов данных, осуществляемым расширением OCI8, обратитесь к типам данных, поддерживаемых драйвером

Список параметров

statement

Корректный идентификатор выражения OCI8, полученный из oci_parse() и исполненный функцией oci_execute(), или идентификатор выражения REF CURSOR.

Также может быть идентификатором, возвращаемым функцией oci_get_implicit_resultset().

mode

Необязательный второй параметр может состоять из любой комбинации следующих констант:

oci_fetch_array() Modes
Константа Описание
OCI_BOTH Возвращает массив как с ассоциативными и числовыми индексами. Эта константа то же самое что и OCI_ASSOC + OCI_NUM, и она используется по умолчанию.
OCI_ASSOC Возвращает ассоциативный массив.
OCI_NUM Возвращает нумерованный массив.
OCI_RETURN_NULLS Создает элементы для полей равных NULL. Значение элемента будет равно PHP NULL.
OCI_RETURN_LOBS Возвращает содержимое полей типа LOB, вместо LOB указателя.

По умолчанию mode равен OCI_BOTH.

Используйте оператор сложения "+" для указания более одного режима.

Возвращаемые значения

Возвращает массив с ассоциативными и/или числовыми ключами. Если больше нет строк в statement, то возвращается FALSE.

По умолчанию, поля LOB возвращаются как указатели LOB.

Поля типа DATE возвращаются в формате строк, соответствующем текущему формату даты. Формат по умолчанию может быть изменен с помощью переменных окружения Oracle, таких как NLS_LANG, или предварительным выполнением команды ALTER SESSION SET NLS_DATE_FORMAT.

Регистронезависимые (по умолчанию в Oracle) имена полей будут иметь ассоциативные индексы в верхнем регистре в результирующем массиве. Регистрозависимые имена полей будут иметь индексы с теми же регистрами символов, что и само поле. Используйте var_dump() для результирующего массива, чтобы проверить соответствие регистров символов для каждого запроса.

Имя таблицы не входит в ассоциативны индекс. Если ваш запрос содержит два разных поля с одинаковым именем, используйте OCI_NUM или добавьте алиас для поля в запрос, так чтобы имена стали уникальными (смотрите пример #7). Иначе будет возвращено только одно поле.

Примеры

Пример #1 oci_fetch_array() с OCI_BOTH

<?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 department_id, department_name FROM departments');
oci_execute($stid);

while ((
$row oci_fetch_array($stidOCI_BOTH))) {
    
// Используйте название полей в верхнем регистре для ассоциативных индексов
    
echo $row[0] . " и " $row['DEPARTMENT_ID']   . " идентичны<br>\n";
    echo 
$row[1] . " и " $row['DEPARTMENT_NAME'] . " идентичны<br>\n";
}

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

?>

Пример #2 oci_fetch_array() с OCI_NUM

<?php

/*
  Перед выполнением создайте таблицу:
      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($stidOCI_NUM)) != false) {
    echo 
$row[0] . "<br>\n";
    echo 
$row[1]->read(11) . "<br>\n"// это выведет первые 11 байт DESCRIPTION
}

// Выведет:
//    1
//    A very long

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

?>

Пример #3 oci_fetch_array() с OCI_ASSOC

<?php

/*
  Перед выполнением создайте таблицу:
      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($stidOCI_ASSOC)) != false) {
    echo 
$row['ID'] . "<br>\n";
    echo 
$row['DESCRIPTION']->read(11) . "<br>\n"// это выведет первые 11 байт DESCRIPTION
}

// Выведет:
//    1
//    A very long

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

?>

Пример #4 oci_fetch_array() с OCI_RETURN_NULLS

<?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 1, null FROM dual');
oci_execute($stid);
while ((
$row oci_fetch_array ($stidOCI_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 ($stidOCI_ASSOC+OCI_RETURN_NULLS)) != false) { // Получает NULL значения
    
var_dump($row);
}

/*
Вышеуказанный код выведет:
  array(2) {
    [1]=>
    string(1) "1"
    ["NULL"]=>
    NULL
  }
*/

?>

Пример #5 oci_fetch_array() с OCI_RETURN_LOBS

<?php

/*
  Перед выполнением создайте таблицу:
      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($stidOCI_ASSOC+OCI_RETURN_LOBS))) {
    echo 
$row['ID'] . "<br>\n";
    echo 
$row['DESCRIPTION'] . "<br>\n"// содержит весь DESCRIPTION
    // В цикле, очищение больших переменных перед повторным получением данных, уменьшает пиковое потребление памяти PHP
    
unset($row); 
}

// Выведет:
//    1
//    A very long string

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

?>

Пример #6 oci_fetch_array() с регистрозависимыми названиями полей

<?php

/*
   Перед выполнением создайте таблицу:
      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($stidOCI_ASSOC+OCI_RETURN_NULLS);

// Так как 'Name' было создан как регистрозависимое поле, то
// те же регисты символов используются для индексов массива.
// Тем не менее для 'CITY' должен использоваться индекс в верхнем регистре.
print $row['Name'] . "<br>\n";   //  выведет Chris
print $row['CITY'] . "<br>\n";   //  выведет Melbourne

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

?>

Пример #7 oci_fetch_array() с полями с одинаковыми названиями

<?php

/*
  Перед выполнением создайте таблицу:
      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($stidOCI_ASSOC);
var_dump($row);

// Выведет только одну записаь "NAME":
//    array(1) {
//      ["NAME"]=>
//      string(9) "Australia"
//    }

// Для получения полей с повторяющимся названием используйте SQL псевдонимы (alias) для полей. Например "AS ctnm":
$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($stidOCI_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

<?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"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($stidOCI_ASSOC);
echo 
$row['HIRE_DATE'] . "<br>\n";  // выведет 1997-06-14

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

?>

Пример #9 oci_fetch_array() с REF CURSOR

<?php
/*
  Создайте 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, -1OCI_B_CURSOR);
oci_execute($stid);

// Выполняет вовзращенный REF CURSOR и получает его в виде идентификатора выражения
oci_execute($refcur);
echo 
"<table border='1'>\n";
while ((
$row oci_fetch_array($refcurOCI_ASSOC+OCI_RETURN_NULLS)) != false) {
    echo 
"<tr>\n";
    foreach (
$row as $item) {
        echo 
"    <td>".($item !== null htmlentities($itemENT_QUOTES) : "&nbsp;")."</td>\n";
    }
    echo 
"</tr>\n";
}
echo 
"</table>\n";

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

?>

Пример #10 Постраничный вывод с помощью oci_fetch_array() используя LIMIT-подобный запрос

<?php

$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 {
    
// Cтарые версии 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;  // skip this many rows
$numrows 5;  // return 5 rows
$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($stidOCI_ASSOC OCI_RETURN_NULLS)) != false) {
    echo 
$row['CITY'] . " " $row['POSTAL_CODE'] . "<br>\n";
}

// Выведет:
//    Beijing 190518
//    Bern 3095
//    Bombay 490231
//    Geneva 1730
//    Hiroshima 6823

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

?>

Пример #11 oci_fetch_array() c Oracle Database 12c Implicit Result Sets

<?php

$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 "<table>\n";
while ((
$row oci_fetch_array($stidOCI_ASSOC+OCI_RETURN_NULLS)) != false) {
    echo 
"<tr>\n";
    foreach (
$row as $item) {
        echo 
"  <td>".($item!==null?htmlentities($itemENT_QUOTES|ENT_SUBSTITUTE):"&nbsp;")."</td>\n";
    }
    echo 
"</tr>\n";
}
echo 
"</table>\n";

// Выведет:
//    Beijing 190518
//    Bern    3095
//    Bombay  490231
//    CN
//    CH
//    IN

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

?>

Примечания

Замечание:

Индексы ассоциативного массива необходимо приводить в верхний регистр для стандартных полей Oracle, созданных с регистронезависимыми названиями.

Замечание:

Для запросов, возвращающих большое количество рядов, производительность может быть значительно увеличена с помощью увеличения значения опции oci8.default_prefetch или использования oci_set_prefetch().

Замечание:

Функция oci_fetch_array() немного медленней oci_fetch_assoc() или oci_fetch_row(), но более гибкая.

Смотрите также

  • oci_fetch() - Выбирает следующую строку из результата в буфер
  • oci_fetch_all() - Выбирает все строки из результата запроса в двумерный массив
  • oci_fetch_assoc() - Возвращает следующую строку из результата запроса в виде ассоциативного массива
  • oci_fetch_object() - Возвращает следующую строку из результата запроса в виде объекта
  • oci_fetch_row() - Возвращает следующую строку из результата запроса в виде нумерованного массива
  • oci_set_prefetch() - Устанавливает количество строк, которые будут автоматически выбраны в буфер