PHP 7.1.18 Released

oci_fetch_array

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

oci_fetch_arrayLiefert die nächste Zeile einer Abfrage als assoziatives oder numerisches Array

Beschreibung

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

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" von Oracle Database 12c zurückgibt, dann werden Zeilen aller Mengen nacheinander geholt. Wurde statement von oci_get_implicit_resultset() zurückgegeben, dann wird nur die Untermenge 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 ebenfalls eine Anweisungskennung sein, die von oci_get_implicit_resultset() zurückgegeben wurde.

mode

Der optionale zweite Parameter kann eine beliebige Kombination aus dem 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 den LOB-Kennungen zurück. descriptors.

Der Standard mode ist OCI_BOTH.

Der Additionsoperator "+" ist zu verwenden, um mehr als einen Modus auf einmal anzugeben.

Rückgabewerte

Liefert ein Array mit assoziativem und/oder numerischem Index. 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 einen zuvor ausgeführten ALTER SESSION SET NLS_DATE_FORMAT Befehl.

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($stidOCI_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($stidOCI_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($stidOCI_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 ($stidOCI_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 ($stidOCI_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($stidOCI_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 Spitzenspeicherbelegung 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($stidOCI_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($stidOCI_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($stidOCI_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 statt dessen 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($stidOCI_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, -1OCI_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($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);

?>

Beispiel #10 Paginierung 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
    // Untermenge von $sql auswählt. Oder, wenn die SQL-Anweisung während der
    // Programmentwicklung bekannt ist, ist die Verwendung einer row_number()
    // Funktion in Betracht zu ziehen. In Produktionsumgebungen ist Sorge zu
    // tragen, 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($stidOCI_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" von Oracle Database 12c

<?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 und Oracle Database 12c
// 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 so nicht verwendet werden
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";

// 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 erstellt wurden, die Groß- und Kleinschreibung nicht unterscheiden, in Großschreibung angegeben werden.

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(), aber ist flexibler.

Siehe auch

add a note add a note

User Contributed Notes 2 notes

up
1
Maxwell_Smart at ThePentagon dot com
15 years ago
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.
up
-2
junk at netburp dot com
17 years ago
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.
To Top