Files
php-doc-ru/reference/oci8/functions/oci-fetch-array.xml
Sergey Panteleev 6d43fd64d7 Исправление форматирования
[skip-spellcheck]
[skip-lint]
2022-12-27 03:42:36 +03:00

693 lines
22 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: ed6de1ae20ce16c0c7be0b3fef282b6065bebfac Maintainer: irker Status: ready -->
<!-- Reviewed: no -->
<refentry xml:id="function.oci-fetch-array" xmlns="http://docbook.org/ns/docbook">
<refnamediv>
<refname>oci_fetch_array</refname>
<refpurpose>Возвращает следующую строку из результата запроса в виде ассоциативного или нумерованного массива
</refpurpose>
</refnamediv>
<refsect1 role="description">
&reftitle.description;
<methodsynopsis>
<type class="union"><type>array</type><type>false</type></type><methodname>oci_fetch_array</methodname>
<methodparam><type>resource</type><parameter>statement</parameter></methodparam>
<methodparam choice="opt"><type>int</type><parameter>mode</parameter><initializer>OCI_BOTH | OCI_RETURN_NULLS</initializer></methodparam>
</methodsynopsis>
<para>
Возвращает массив, содержащий следующую строку результата запроса.
Каждый элемент массива соответствует одному полю из строки. Эта функция
обычно вызывается в цикле, пока она не вернёт &false;, который указывает
на отсутствие последующих строк.
</para>
<para>
Если <parameter>statement</parameter> соответствует PL/SQL блоку,
возвращаемому Oracle Database Implicit Result Sets, тогда будут
последовательно извлечены ряды из всех наборов.
Если <parameter>statement</parameter> возвращается из
<function>oci_get_implicit_resultset</function>, тогда вернётся только
часть рядов для одного дочернего запроса.
</para>
&oci.datatypes;
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;
<para>
<variablelist>
<varlistentry>
<term><parameter>statement</parameter></term>
<listitem>
&oci.arg.statement.id;
<para>
Также может быть идентификатором, возвращаемым функцией <function>oci_get_implicit_resultset</function>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>mode</parameter></term>
<listitem>
<para>
Необязательный второй параметр может состоять из любой комбинации следующих
констант:
<table>
<title><function>oci_fetch_array</function> Modes</title>
<tgroup cols="2">
<thead>
<row>
<entry>Константа</entry>
<entry>Описание</entry>
</row>
</thead>
<tbody>
<row>
<entry><constant>OCI_BOTH</constant></entry>
<entry>Возвращает массив как с ассоциативными и числовыми
индексами. Эта константа то же самое что и
<constant>OCI_ASSOC</constant>
+ <constant>OCI_NUM</constant>, и она используется по умолчанию.</entry>
</row>
<row>
<entry><constant>OCI_ASSOC</constant></entry>
<entry>Возвращает ассоциативный массив.</entry>
</row>
<row>
<entry><constant>OCI_NUM</constant></entry>
<entry>Возвращает нумерованный массив.</entry>
</row>
<row>
<entry><constant>OCI_RETURN_NULLS</constant></entry>
<entry>Создаёт элементы для полей равных &null;. Значение элемента
будет равно PHP &null;.
</entry>
</row>
<row>
<entry><constant>OCI_RETURN_LOBS</constant></entry>
<entry>Возвращает содержимое полей типа LOB, вместо LOB
указателя.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
По умолчанию <parameter>mode</parameter> равен <constant>OCI_BOTH</constant>.
</para>
<para>
Используйте оператор сложения "+" для указания
более одного режима.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1 role="returnvalues">
&reftitle.returnvalues;
<para>
Возвращает массив с ассоциативными и/или числовыми ключами. Если
больше нет строк в <parameter>statement</parameter>, то возвращается
&false;.
</para>
<para>
По умолчанию, поля <literal>LOB</literal> возвращаются как указатели LOB.
</para>
<para>
Поля типа <literal>DATE</literal> возвращаются в формате строк, соответствующем
текущему формату даты. Формат по умолчанию может быть изменён
с помощью переменных окружения Oracle, таких как <literal>NLS_LANG</literal>, или
предварительным выполнением команды <literal>ALTER SESSION SET
NLS_DATE_FORMAT</literal>.
</para>
<para>
Регистронезависимые (по умолчанию в Oracle) имена полей будут иметь
ассоциативные индексы в верхнем регистре в результирующем массиве.
Регистрозависимые имена полей будут иметь индексы с теми же регистрами символов, что и само поле.
Используйте <function>var_dump</function> для результирующего массива, чтобы
проверить соответствие регистров символов для каждого запроса.
</para>
<para>
Имя таблицы не входит в ассоциативны индекс. Если ваш запрос
содержит два разных поля с одинаковым именем, используйте <constant>OCI_NUM</constant>
или добавьте алиас для поля в запрос, так чтобы имена стали уникальными (смотрите пример #7).
Иначе будет возвращено только одно поле.
</para>
</refsect1>
<refsect1 role="examples">
&reftitle.examples;
<para>
<example>
<title><function>oci_fetch_array</function> с <constant>OCI_BOTH</constant></title>
<programlisting role="php">
<![CDATA[
<?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);
?>
]]>
</programlisting>
</example>
</para>
<para>
<example>
<title><function>oci_fetch_array</function> с <constant>OCI_NUM</constant></title>
<programlisting role="php">
<![CDATA[
<?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);
?>
]]>
</programlisting>
</example>
</para>
<para>
<example>
<title><function>oci_fetch_array</function> с <constant>OCI_ASSOC</constant></title>
<programlisting role="php">
<![CDATA[
<?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);
?>
]]>
</programlisting>
</example>
</para>
<para>
<example>
<title><function>oci_fetch_array</function> с <constant>OCI_RETURN_NULLS</constant></title>
<programlisting role="php">
<![CDATA[
<?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
}
*/
?>
]]>
</programlisting>
</example>
</para>
<para>
<example>
<title><function>oci_fetch_array</function> с <constant>OCI_RETURN_LOBS</constant></title>
<programlisting role="php">
<![CDATA[
<?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);
?>
]]>
</programlisting>
</example>
</para>
<para>
<example>
<title><function>oci_fetch_array</function> с регистрозависимыми названиями полей</title>
<programlisting role="php">
<![CDATA[
<?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);
?>
]]>
</programlisting>
</example>
</para>
<para>
<example>
<title><function>oci_fetch_array</function> с полями с одинаковыми названиями</title>
<programlisting role="php">
<![CDATA[
<?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);
?>
]]>
</programlisting>
</example>
</para>
<para>
<example>
<title><function>oci_fetch_array</function> с полями <literal>DATE</literal></title>
<programlisting role="php">
<![CDATA[
<?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);
?>
]]>
</programlisting>
</example>
</para>
<para>
<example>
<title><function>oci_fetch_array</function> с <literal>REF CURSOR</literal></title>
<programlisting role="php">
<![CDATA[
<?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);
?>
]]>
</programlisting>
</example>
</para>
<para>
<example>
<title>Постраничный вывод с помощью <function>oci_fetch_array</function> используя <literal>LIMIT</literal>-подобный запрос</title>
<programlisting role="php">
<![CDATA[
<?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);
?>
]]>
</programlisting>
</example>
</para>
<para>
<example>
<title><function>oci_fetch_array</function> c Oracle Database Implicit Result Sets</title>
<programlisting role="php">
<![CDATA[
<?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);
?>
]]>
</programlisting>
</example>
</para>
</refsect1>
<refsect1 role="notes">
&reftitle.notes;
<note>
<para>
Индексы ассоциативного массива необходимо приводить в верхний регистр
для стандартных полей Oracle, созданных с регистронезависимыми названиями.
</para>
</note>
<note>
&oci.use.setprefetch;
</note>
<note>
<para>
Функция <function>oci_fetch_array</function>
<emphasis>немного</emphasis> медленней
<function>oci_fetch_assoc</function>
или <function>oci_fetch_row</function>, но более гибкая.
</para>
</note>
</refsect1>
<refsect1 role="seealso">
&reftitle.seealso;
<para>
<simplelist>
<member><function>oci_fetch</function></member>
<member><function>oci_fetch_all</function></member>
<member><function>oci_fetch_assoc</function></member>
<member><function>oci_fetch_object</function></member>
<member><function>oci_fetch_row</function></member>
<member><function>oci_set_prefetch</function></member>
</simplelist>
</para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->