oci_fetch_array
(PHP 5, PHP 7, PHP 8, PECL OCI8 >= 1.1.0)
oci_fetch_array — Liefert die nächste Zeile einer Abfrage als assoziatives oder numerisches Array
Beschreibung
$statement
, int $mode
= OCI_BOTH | OCI_RETURN_NULLS): array|false
Gibt ein Array zurück, das die nächste Zeile der Ergebnismenge einer
Abfrage enthält. Jedes Array-Element entspricht einer Spalte der Zeile.
Diese Funktion wird üblicherweise in einer Schleife aufgerufen, bis sie
false
zurückgibt, was anzeigt, dass es keine weiteren Zeilen gibt.
Bezieht sich statement
auf einen PL/SQL-Block, der
implizite Ergebnismengen einer Oracle-Datenbank zurückgibt, dann werden die
Zeilen aller Mengen nacheinander abgerufen. Wurde
statement
von
oci_get_implicit_resultset() zurückgegeben, dann wird
nur die Teilmenge der Zeilen für eine Kindabfrage zurückgegeben.
Für Details zur vom OCI8-Treiber durchgeführten Umsetzung von Datentypen siehe die vom Treiber unterstützen Datentypen.
Parameter-Liste
-
statement
-
Der Identifizierer eines gültigen OCI8-Ausdrucks, der von oci_parse() erzeugt und von oci_execute() oder einem
REF CURSOR
-Ausdruck verwendet wird.Kann auch eine Anweisungskennung sein, die von oci_get_implicit_resultset() zurückgegeben wurde.
-
mode
-
Der optionale zweite Parameter kann eine beliebige Kombination aus den folgenden Konstanten sein:
oci_fetch_array()-Modi Konstante Beschreibung OCI_BOTH
Gibt ein Array mit sowohl assoziativen als auch numerischen Indizes zurück. Das ist dasselbe wie OCI_ASSOC
+OCI_NUM
und ist das Standardverhalten.OCI_ASSOC
Gibt ein assoziatives Array zurück. OCI_NUM
Gibt ein numerisches Array zurück. OCI_RETURN_NULLS
Erzeugt Elemente für null
-Felder. Die Elementwerte sind PHP-null
-Werte.OCI_RETURN_LOBS
Gibt den Inhalt von LOBs statt der LOB-Kennungen zurück. Der Standard-
mode
istOCI_BOTH
.Der Additionsoperator "+" ist zu verwenden, um mehr als einen Modus auf einmal anzugeben.
Rückgabewerte
Gibt ein Array mit assoziativen und/oder numerischen Indizes zurück. Gibt
es keine weiteren Zeilen in statement
, wird false
zurückgegeben.
Standardmäßig werden LOB
-Spalten als LOB-Kennungen
zurückgegeben.
DATE
-Spalten werden als gemäß des aktuellen
Datumsformats formatierte Zeichenketten zurückgegeben. Das Standardformat
kann mit Oracle-Umgebungsvariablen wie NLS_LANG
geändert
werden oder auch durch den zuvor ausgeführten Befehl ALTER
SESSION SET NLS_DATE_FORMAT
.
Die standardmäßigen Oracle-Spaltennamen, die nicht zwischen Groß- und Kleinschreibung unterscheiden, erzeugen Arrayschlüssel in Großbuchstaben. Spaltennamen, die zwischen Groß- und Kleinschreibung unterscheiden, verwenden die genaue Schreibweise. var_dump() kann auf das Ergebnisarray angewendet werden, um die richtige Schreibweise für jede Abfrage zu prüfen.
Der Tabellenname ist nicht im Arrayschlüssel enthalten. Enthält die Abfrage
zwei unterschiedliche Spalten mit demselben Namen ist
OCI_NUM
zu verwenden, oder ein Spaltenalias sollte in
der Abfrage definiert werden, um die Eindeutigkeit der Namen
sicherzustellen; siehe Beispiel #7. Andernfalls wird nur eine der Spalten
von PHP zurückgegeben.
Beispiele
Beispiel #1 oci_fetch_array() mit 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)) != false) {
// verwende Spaltennamen in Großschreibung für die assoziativen Arrayschlüssel
echo $row[0] . " und " . $row['DEPARTMENT_ID'] . " sind dasselbe<br>\n";
echo $row[1] . " und " . $row['DEPARTMENT_NAME'] . " sind dasselbe<br>\n";
}
oci_free_statement($stid);
oci_close($conn);
?>
Beispiel #2 oci_fetch_array() mit OCI_NUM
<?php
/*
Vor der Ausführung ist die Tabelle zu erstellen:
CREATE TABLE mytab (id NUMBER, description CLOB);
INSERT INTO mytab (id, description) values (1, 'Eine sehr lange Zeichenkette');
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(15) . "<br>\n"; // dies gibt die ersten 15 Bytes von DESCRIPTION aus
}
// die Ausgabe ist:
// 1
// Eine sehr lange
oci_free_statement($stid);
oci_close($conn);
?>
Beispiel #3 oci_fetch_array() mit OCI_ASSOC
<?php
/*
Vor der Ausführung ist die Tabelle zu erstellen:
CREATE TABLE mytab (id NUMBER, description CLOB);
INSERT INTO mytab (id, description) values (1, 'Eine sehr lange Zeichenkette');
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(15) . "<br>\n"; // dies gibt die ersten 15 Bytes von DESCRIPTION aus
}
// die Ausgabe ist:
// 1
// Eine sehr lange
oci_free_statement($stid);
oci_close($conn);
?>
Beispiel #4 oci_fetch_array() mit 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) { // ignoriere NULL-Werte
var_dump($row);
}
/*
Der obige Code gibt aus:
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) { // hole NULL-Werte
var_dump($row);
}
/*
Der obige Code gibt aus:
array(2) {
[1]=>
string(1) "1"
["NULL"]=>
NULL
}
*/
?>
Beispiel #5 oci_fetch_array() mit OCI_RETURN_LOBS
<?php
/*
Vor der Ausführung ist die Tabelle zu erstellen:
CREATE TABLE mytab (id NUMBER, description CLOB);
INSERT INTO mytab (id, description) values (1, 'Eine sehr lange Zeichenkette');
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'] . "<br>\n";
echo $row['DESCRIPTION'] . "<br>\n"; // dies enthält die gesamte DESCRIPTION
// das Freigeben der großen Variable in einer Schleife vor dem zweiten Fetch
// verringert die maximale Speicherbelegung von PHP
unset($row);
}
// die Ausgabe ist:
// 1
// Eine sehr lange Zeichenkette
oci_free_statement($stid);
oci_close($conn);
?>
Beispiel #6 oci_fetch_array() mit Spaltennamen, die zwischen Groß- und Kleinschreibung unterscheiden
<?php
/*
Vor der Ausführung ist die Tabelle zu erstellen:
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);
// Da 'Name' als Spalte erstellt wurde, die zwischen Groß- und Kleinschreibung
// unterscheidet, muss genau dieselbe Schreibweise für den Arrayschlüssel
// verwendet werden. Allerding muss das groß geschriebene 'CITY' für den
// Spaltenschlüssel verwendet werden, der nicht zwischen Groß- und
// Kleinschreibung unterscheidet.
print $row['Name'] . "<br>\n"; // gibt Chris aus
print $row['CITY'] . "<br>\n"; // gibt Melbourne aus
oci_free_statement($stid);
oci_close($conn);
?>
Beispiel #7 oci_fetch_array() mit Spalten, die doppelte Namen haben
<?php
/*
Vor der Ausführung ist die Tabelle zu erstellen:
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, 'Australien');
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);
// die Ausgabe enthält nur ein "NAME"-Element:
// array(1) {
// ["NAME"]=>
// string(9) "Australien"
// }
// um einen sich wiederholenden Spaltennamen abzufragen, ist ein
// SQL-Spaltenalias wie "AS ctnm" zu verwenden:
$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);
// die Ausgabe enthält nun die beiden gewählten Spalten:
// array(2) {
// ["CTNM"]=>
// string(9) "Melbourne"
// ["NAME"]=>
// string(9) "Australien"
// }
oci_free_statement($stid);
oci_close($conn);
?>
Beispiel #8 oci_fetch_array() mit DATE
-Spalten
<?php
$conn = oci_connect('hr', 'welcome', 'localhost/XE');
if (!$conn) {
$e = oci_error();
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}
// Lege das Datumsformat für diese Verbindung fest.
// Aus Effizienzgründen ist zu erwägen, das Format stattdessen in
// einem Trigger oder mit Umgebungsvariablen zu ändern.
$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"; // gibt 1997-06-14 aus
oci_free_statement($stid);
oci_close($conn);
?>
Beispiel #9 oci_fetch_array() mit REF CURSOR
<?php
/*
Erzeuge die PL/SQL gespeicherte Prozedur mit:
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);
// führe den zurückgegebenen REF CURSOR aus und lies
// von ihm wie mit einer Anweisungskennung
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);
?>
Beispiel #10 Seitenweise Darstellung mit oci_fetch_array() unter Verwendung einer LIMIT
-Klausel
<?php
$conn = oci_connect('hr', 'welcome', 'localhost/XE');
if (!$conn) {
$e = oci_error();
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}
// ermittle die Datenbankversion
preg_match('/Release ([0-9]+)\./', oci_server_version($conn), $matches);
$oracleversion = $matches[1];
// dies ist die Abfrage, durch die seitenweise geblättert werden soll
$sql = 'SELECT city, postal_code FROM locations ORDER BY city';
if ($oracleversion >= 12) {
// verwende die OFFSET / FETCH NEXT-Syntax von Oracle 12c
$sql = $sql . ' OFFSET :offset ROWS FETCH NEXT :numrows ROWS ONLY';
} else {
// Ältere Oracle-Versionen benötigten eine verschachtelte Abfrage, die
// eine Teilmenge von $sql auswählt. Wenn die SQL-Anweisung zum Zeitpunkt
// der Programmentwicklung bekannt ist, sollte statt dieser Methode eine
// row_number()-Funktion verwendet werden. In Produktionsumgebungen ist
// darauf zu achten, dass SQL-Injection-Probleme durch
// Zeichenkettenverknüpfung vermieden werden.
$sql = "SELECT * FROM (SELECT a.*, ROWNUM AS my_rnum
FROM ($sql) a
WHERE ROWNUM <= :offset + :numrows)
WHERE my_rnum > :offset";
}
$offset = 0; // lasse so viele Zeilen aus
$numrows = 5; // gib 5 Zeilen zurück
$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";
}
// die Ausgabe ist:
// Beijing 190518
// Bern 3095
// Bombay 490231
// Geneva 1730
// Hiroshima 6823
oci_free_statement($stid);
oci_close($conn);
?>
Beispiel #11 oci_fetch_array() mit impliziten Ergebnismengen einer Oracle-Datenbank
<?php
$conn = oci_connect('hr', 'welcome', 'localhost/pdborcl');
if (!$conn) {
$e = oci_error();
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}
// Benötigt OCI8 2.0 (oder höher) und Oracle Database 12c (oder höher)
// siehe auch 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);
// Beachte: oci_fetch_all und oci_fetch() können nicht auf diese Weise
// verwendet werden
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";
// die Ausgabe ist:
// Beijing 190518
// Bern 3095
// Bombay 490231
// CN
// CH
// IN
oci_free_statement($stid);
oci_close($conn);
?>
Anmerkungen
Hinweis:
Assoziative Arrayschlüssel müssen für Standard-Oracle-Spalten, die mit Namen ohne Berücksichtigung der Groß- und Kleinschreibung erstellt wurden, in Großbuchstaben sein.
Hinweis:
Bei Queries, die eine große Anzahl an Zeilen zurückliefern, kann die Laufzeit beträchtlich verbessert werden, indem man oci8.default_prefetch erhöht oder oci_set_prefetch() verwendet.
Hinweis:
Die Funktion oci_fetch_array() ist unwesentlich langsamer als oci_fetch_assoc() oder oci_fetch_row(), ist aber flexibler.
Siehe auch
- oci_fetch() - Ruft die nächste Zeile einer Abfrage in einen internen Puffer ab
- oci_fetch_all() - Ruft mehrere Datensätze einer Abfrage in ein zweidimensionales Array ab
- oci_fetch_assoc() - Liefert die nächste Zeile einer Abfrage als assoziatives Array
- oci_fetch_object() - Liefert die nächste Zeile einer Abfrage als Objekt
- oci_fetch_row() - Liefert die nächste Zeile einer Abfrage als numerisches Array
- oci_set_prefetch() - Sets number of rows to be prefetched by queries