oci_fetch_array
(PHP 5, PHP 7, PECL OCI8 >= 1.1.0)
oci_fetch_array — Возвращает следующую строку из результата запроса в виде ассоциативного или нумерованного массива
Описание
$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
. Значение элемента будет равно PHPNULL
.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($stid, OCI_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($stid, OCI_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($stid, OCI_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 ($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
<?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($stid, OCI_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($stid, OCI_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($stid, OCI_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($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
<?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($stid, OCI_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, -1, OCI_B_CURSOR);
oci_execute($stid);
// Выполняет вовзращенный REF CURSOR и получает его в виде идентификатора выражения
oci_execute($refcur);
echo "<table border='1'>\n";
while (($row = oci_fetch_array($refcur, OCI_ASSOC+OCI_RETURN_NULLS)) != false) {
echo "<tr>\n";
foreach ($row as $item) {
echo " <td>".($item !== null ? htmlentities($item, ENT_QUOTES) : " ")."</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($stid, OCI_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($stid, OCI_ASSOC+OCI_RETURN_NULLS)) != false) {
echo "<tr>\n";
foreach ($row as $item) {
echo " <td>".($item!==null?htmlentities($item, ENT_QUOTES|ENT_SUBSTITUTE):" ")."</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() - Устанавливает количество строк, которые будут автоматически выбраны в буфер
- PHP Руководство
- Функции по категориям
- Индекс функций
- Справочник функций
- Расширения для работы с базами данных
- Расширения для работы с базами данных отдельных производителей
- Oracle OCI8
- oci_bind_array_by_name
- oci_bind_by_name
- oci_cancel
- oci_client_version
- oci_close
- oci_commit
- oci_connect
- oci_define_by_name
- oci_error
- oci_execute
- oci_fetch_all
- oci_fetch_array
- oci_fetch_assoc
- oci_fetch_object
- oci_fetch_row
- oci_fetch
- oci_field_is_null
- oci_field_name
- oci_field_precision
- oci_field_scale
- oci_field_size
- oci_field_type_raw
- oci_field_type
- oci_free_descriptor
- oci_free_statement
- oci_get_implicit_resultset
- oci_internal_debug
- oci_lob_copy
- oci_lob_is_equal
- oci_new_collection
- oci_new_connect
- oci_new_cursor
- oci_new_descriptor
- oci_num_fields
- oci_num_rows
- oci_parse
- oci_password_change
- oci_pconnect
- oci_result
- oci_rollback
- oci_server_version
- oci_set_action
- oci_set_client_identifier
- oci_set_client_info
- oci_set_edition
- oci_set_module_name
- oci_set_prefetch
- oci_statement_type
Коментарии
Here's a clue about rowid.
Don't forget about the oracle functions:
"rowidtochar" and "chartorowid"
"select rowidtochar(rowid) as FOO from table ...."
When you want to pass the rowid in a form or link, that's
the only way to go.
When using OCI_RETURN_LOBS to get a BFILE (stored with a DIRECTORY) the user needs READ on the DIRECTORY. (GRANT READ on DIRECTORY <directory name> TO <user>;) Otherwise, you'll get a cryptic error. Warning: OCILobFileOpen: ORA-22285: non-existent directory or file for FILEOPEN operation in ... on line ...
<BR>
The user that CREATEs the DIRECTORY is automatically GRANTed READ WITH THE GRANT OPTION.