(PHP 5, PHP 7, PECL OCI8 >= 1.1.0)
oci_fetch_array — Lit une ligne d'un résultat sous forme de tableau associatif ou numérique
$statement
[, int $mode
] )
Retourne un tableau contenant la prochaine ligne d'une requête.
Chaque entrée de ce tableau correspond à une colonne de la ligne.
Cette fonction est appelée typiquement dans une boucle qui retourne
FALSE
lorsqu'il n'y a plus de ligne de disponible.
Si le paramètre statement
correspond à un bloc PL/SQL
retourné par des jeux de résultats implicites Oracle Database 12c,
alors les lignes depuis tous les jeux de résultats seront récupérées
consécutivement. Si statement
est retourné par
la fonction oci_get_implicit_resultset(), alors seul
le sous-jeu de lignes d'une seule requête enfant sera retourné.
Pour plus de détails sur le mapping des types de données effectué par l'extension OCI8, lisez les types de données supportés par le driver.
statement
Un identifiant de requête OCI8 créé par la fonction oci_parse() et exécuté par la fonction oci_execute(), ou un identifiant de requête REF CURSOR.
Peut également être un identifiant de requête retourné par la fonction oci_get_implicit_resultset().
mode
Le paramètre optionnel mode
peut être la
combinaison des constantes suivantes :
Constante | Description |
---|---|
OCI_BOTH |
Retourne une tableau, indexé numériquement et avec les noms
de colonnes. Identique à OCI_ASSOC +
OCI_NUM ). C'est le comportement par défaut. |
OCI_ASSOC |
Retourne un tableau associatif. |
OCI_NUM |
Retourne un tableau indexé numériquement. |
OCI_RETURN_NULLS |
Crée des éléments vides pour les valeurs NULL . La valeur
des éléments sera la valeur NULL PHP.
|
OCI_RETURN_LOBS |
Retourne le contenu du LOB au lieu de leur descripteur. |
Le mode
par défaut est OCI_BOTH
.
Utilisez l'opérateur d'addition "+" pour spécifier plus d'un mode à la fois.
Retourne un tableau avec des indices numériques ou associatifs. S'il n'y a plus de ligne
de disponible pour la requête statement
alors FALSE
sera retourné.
Par défaut, les colonnes LOB sont retournées sous la forme de descripteurs LOB.
Les colonnes DATE sont retournées sous la forme d'une chaîne formatée avec le format de date courante. Le format par défaut peut être modifié grâce aux variables d'environnement Oracle, comme NLS_LANG ou par l'exécution de la commande ALTER SESSION SET NLS_DATE_FORMAT.
Les noms de colonnes qui ne sont pas sensibles à la casse (par défaut sous Oracle), auront des noms d'attributs en majuscule. Les noms de colonnes qui sont sensibles à la casse, auront des noms d'attributs utilisant exactement la même casse de la colonne. Utilisez la fonction var_dump() sur l'objet de résultat pour vérifier la casse appropriée à utiliser pour chaque requête.
Le nom de la table n'est pas inclus dans l'index du tableau. Si votre requête
contient deux colonnes différentes avec le même nom, utilisez la constante
OCI_NUM
ou ajoutez un alias à la colonne à la requête
pour s'assurer l'unicité du nom ; voir l'exemple #7. Sinon, seulement une
colonne sera retournée via PHP.
Exemple #1 Exemple avec oci_fetch_array() avec 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) {
// Utilisez des noms de colonne en majuscule pour les indices des tableau associatif
echo $row[0] . " and " . $row['DEPARTMENT_ID'] . " are the same<br>\n";
echo $row[1] . " and " . $row['DEPARTMENT_NAME'] . " are the same<br>\n";
}
oci_free_statement($stid);
oci_close($conn);
?>
Exemple #2 Exemple avec oci_fetch_array() avec
OCI_NUM
<?php
/*
Avant l'exécution, créez la table :
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"; // ceci affichera les 11 premiers octets depuis DESCRIPTION
}
// Affiche :
// 1
// A very long
oci_free_statement($stid);
oci_close($conn);
?>
Exemple #3 Exemple avec oci_fetch_array() avec
OCI_ASSOC
<?php
/*
Avant l'exécution, créez la table :
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"; // ceci affichera les 11 premiers octets depuis DESCRIPTION
}
// Affiche :
// 1
// A very long
oci_free_statement($stid);
oci_close($conn);
?>
Exemple #4 Exemple avec oci_fetch_array() avec
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) { // Ignore NULLs
var_dump($row);
}
/*
Le code ci-dessus affiche :
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) { // Récupère NULLs
var_dump($row);
}
/*
Le code ci-dessus affiche :
array(2) {
[1]=>
string(1) "1"
["NULL"]=>
NULL
}
*/
?>
Exemple #5 oci_fetch_array() with OCI_RETURN_LOBS
<?php
/*
Avant l'exécution, créez la table :
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)) != false) {
echo $row['ID'] . "<br>\n";
echo $row['DESCRIPTION'] . "<br>\n"; // contient la totalité de DESCRIPTION
// Dans une boucle, le fait de libérer la variable avant de récupérer une seconde
// ligne permet de réduire l'utilisation mémoire de PHP
unset($row);
}
// Affiche :
// 1
// A very long string
oci_free_statement($stid);
oci_close($conn);
?>
Exemple #6 Exemple avec oci_fetch_array() avec des noms de colonnes sensibles à la casse
<?php
/*
Avant l'exécution, créez la table :
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);
// Vu que 'Name' a été créé comme une colonne sensible à la casse, la même casse
// est utilisé pour les index du tableau. Cependant, 'CITY' doit être utilisé
// pour les index de colonne non sensible à la casse
print $row['Name'] . "<br>\n"; // affiche Chris
print $row['CITY'] . "<br>\n"; // affiche Melbourne
oci_free_statement($stid);
oci_close($conn);
?>
Exemple #7 Exemple avec oci_fetch_array() avec des colonnes possédant des noms dupliqués
<?php
/*
Avant l'exécution, créez la table :
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);
// L'affiche ne contient que UNE entrée "NAME" :
// array(1) {
// ["NAME"]=>
// string(9) "Australia"
// }
// Pour interroger un nom de colonne dupliqué, utilisez un alias de colonne SQL
// comme "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);
// L'affichage contient maintenant 2 colonnes :
// array(2) {
// ["CTNM"]=>
// string(9) "Melbourne"
// ["NAME"]=>
// string(9) "Australia"
// }
oci_free_statement($stid);
oci_close($conn);
?>
Exemple #8 Exemple avec oci_fetch_array() et des colonnes DATE
<?php
$conn = oci_connect('hr', 'welcome', 'localhost/XE');
if (!$conn) {
$e = oci_error();
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}
// Définit le format utilisé pour les dates sur cette connexion.
// Pour des raisons de performance, vous devriez modifier le format via un trigger ou
// en utilisant les variables d'environnement
$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"; // Affiche 1997-06-14
oci_free_statement($stid);
oci_close($conn);
?>
Exemple #9 Exemple avec oci_fetch_array() et REF CURSOR
<?php
/*
Créez la procédure stockée PL/SQL suivante avant l'exécution :
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);
// Exécute le REF CURSOR retourné et y récupère un identifiant de requête
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);
?>
Exemple #10 Pagination avec oci_fetch_array() en utilisant une requête utilisant le paramètre LIMIT
<?php
$conn = oci_connect('hr', 'welcome', 'localhost/XE');
if (!$conn) {
$e = oci_error();
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}
// Retrouve la version de la base de données
preg_match('/Release ([0-9]+)\./', oci_server_version($conn), $matches);
$oracleversion = $matches[1];
// Requête pour la pagination
$sql = 'SELECT city, postal_code FROM locations ORDER BY city';
if ($oracleversion >= 12) {
// Utilisation de la syntaxe Oracle 12c OFFSET / FETCH NEXT
$sql = $sql . ' OFFSET :offset ROWS FETCH NEXT :numrows ROWS ONLY';
} else {
// Les versions anciennes d'Oracle ont besoin d'une requête imbriquée
// pour sélectionner un sous-jeu depuis $sql. Ou, si la requête SQL
// est connue au moment du développement, utilisez plutôt une fonction
// row_number() au lieu de cette solution d'imbrication. Dans les
// environnements de production, assurez-vous d'éviter les injections
// SQL avec la concaténation.
$sql = "SELECT * FROM (SELECT a.*, ROWNUM AS my_rnum
FROM ($sql) a
WHERE ROWNUM <= :offset + :numrows)
WHERE my_rnum > :offset";
}
$offset = 0; // Ne pas traiter les premières lignes
$numrows = 5; // Retourne 5 lignes
$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";
}
// Affiche :
// Beijing 190518
// Bern 3095
// Bombay 490231
// Geneva 1730
// Hiroshima 6823
oci_free_statement($stid);
oci_close($conn);
?>
Exemple #11 Exemple avec oci_fetch_array() avec 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);
}
// Requiert OCI8 2.0 et Oracle Database 12c
// Voir aussi 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);
// Note : oci_fetch_all et oci_fetch() ne peuvent être utilisées de cette façon
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";
// Affiche :
// Beijing 190518
// Bern 3095
// Bombay 490231
// CN
// CH
// IN
oci_free_statement($stid);
oci_close($conn);
?>
Note:
Les indices des tableaux associatifs doivent être en majuscule pour les colonnes standards Oracle qui ont été créée avec des noms sensibles à la casse.
Note:
Pour les requêtes retournant un très grand nombre de lignes, les performances peuvent être très grandement accrues en augmentant la valeur de l'option oci8.default_prefetch ou en utilisant la fonction oci_set_prefetch().
Note:
La fonction oci_fetch_array() est significativement plus lente que la fonction oci_fetch_assoc() ou oci_fetch_row(), mais est plus flexible.