The manual Page
English version
accueil | glossaire | downloads | liens ]
 

Connexion à une base de données Oracle

Introduction

Ce qui suit permet de se connecter et d'effectuer des requêtes PL/SQL (le SQL d'Oracle) sur des serveurs Oracle 7 et 8i.

Les fonctions permettant la connexion à une base Oracle depuis PHP ont été écrites avec la librairie OCI8 (Oracle8 Call-Interface) d'Oracle. C'est pourquoi toutes ces fonctions commencent par "OCI".

Connexion au serveur

La connexion à un serveur Oracle se fait avec la fonction OCILogOn :

$connexion = OCILogOn("utilisateur", "mot_de_passe", $bdd);

Cette ligne de commande va permettre de se connecter au schéma Oracle $bdd. $bdd est une chaîne de connexion définie dans le fichier tnsnames.ora. Par exemple, $bdd vaudra "MA_BDD" si tnsnames.ora contient une séquence comme celle-ci :

MA_BDD =
  (DESCRIPTION =
    (ADDRESS =
      (PROTOCOL = TCP)
      (HOST = mon.serveur.oracle.com)
      (PORT = 1521)
    )
    (CONNECT_DATA = (SID = ORACLE)
    )
  )

Exécuter une requête PL/SQL

Cela se passe en deux étapes : la préparation de la requête, et l'exécution de la requéte proprement dite.

La préparation s'effectue avec la fonction OCIParse :

$stmt = OCIParse($connexion, "SELECT * FROM table");

OCIParse utilise deux arguments : un identifiant de connexion (résultat de la fonction OCILogOn) et la requête. Le résultat de cette opération sera utilisé par la suite du programme pour exécuter la requête et exploiter le résultat. On peut combiner deux OCIParse sur le même identifiant de connexion ($connexion) et récupérer les 2 résultats dans 2 variables $stmt1 et $stmt2 pour exécuter 2 requêtes en même temps sur la même base.

L'exécution s'effectue ensuite avec la fonction OCIExecute :

OCIExecute($stmt);

Cette fonction prend en argument le résultat renvoyé par OCIParse.

Les appels de procédures stockées et les macros PL/SQL se font exactement de la même façon :

$stmt = OCIParse($connexion, "BEGIN PROCEDURE_STOCKEE(:arg1, :arg2); END;");
OCIBindByName($stmt, ":arg1", &$arg1, -1);
OCIBindByName($stmt, ":arg2", &$arg2, -1);
OCIExecute($stmt);

L'utilisation de OCIBindByName sera expliquée plus bas.

Notez qu'une requéte PL/SQL normale (SELECT, UPDATE, INSERT...) ne se termine pas par un point-virgule (";"), alors que l'appel à une procédure stockée se termine avec un point-virgule (";").

Lire le résultat d'une requête

Il faut utiliser conjointement 2 fonctions : OCIFetch et OCIResult. OCIFetch permet de récupérer une ligne du résultat, alors que OCIResult permet de lire une valeur d'une ligne récupérée par OCIFetch. Dans l'exemple suivant, on va interroger la table articles contenant les colonnes article et prix :

$stmt = OCIParse($connexion, "SELECT * FROM articles WHERE prix<=100");
OCIExecute($stmt);
$compteur = 0;
while (OCIFetch($stmt)) {
	$compteur++;
	echo OCIResult($stmt, "ARTICLE")." coûte ";
	echo OCIResult($stmt, "PRIX")." F<BR>\n";
}
OCIFreeStatement($stmt);
echo "$compteur articles trouvés.";

Ces deux fonctions utilisent, comme OCIExecute la variable $stmt renvoyée par OCIParse.

Attention ! Le nom des colonnes utilisé avec OCIResult doit être en majuscule.

Même si la requéte ne renvoie qu'une seule ligne (cas d'un "SELECT COUNT(*)" par exemple), il est indispensable de faire un OCIFetch pour récupérer le résultat. Exemple :

$query = "SELECT COUNT(*) total FROM articles WHERE prix<=100";
$stmt = OCIParse($connexion, $query);
OCIExecute($stmt);
OCIFetch($stmt);
echo OCIResult($stmt, "TOTAL")." articles à moins de 100 F.";
OCIFreeStatement($stmt);

Vous noterez l'utilisation d'une variable $compteur dans l'exemple précédent. Cela n'est pas innocent. En effet, contrairement à MySQL et la fonction mysql_num_rows, il n'est pas possible de connaître directement le nombre de lignes renvoyées par une requête SELECT. Il existe pourtant une fonction OCIRowCount, mais elle ne permet de récupérer qu'un nombre de lignes modifiées. On ne peut l'utiliser qu'avec une requête UPDATE ou INSERT, par exemple.

Paramètres de procédures stockées et variables longues

On construit très souvent des requêtes SQL dynamiques en insérant directement dans la requéte la valeur des variables :

$query = "SELECT * FROM personnel WHERE nom='$nom'";
$stmt = OCIParse($connexion, $query);
OCIExecute($stmt);
while (OCIFetch($stmt)) {
	...
}
OCIFreeStatement($stmt);

Cela est très pratique, mais pour les variables très grandes (des textes renvoyés par des formulaires par exemple), on se trouve confronté à un problème : on ne peut pas écrire de requête contenant plus de 4000 caractères environ. Ce problème se résoud en utilisant la fonction OCIBindByName :

$stmt = OCIParse($connexion, "INSERT INTO memos (texte) VALUES (:texte)");
OCIBindByName($stmt, ":texte", &$texte_formulaire, -1);
OCIExecute($stmt);
OCIFreeStatement($stmt);

OCIBindByName va alors associer la variable $texte_formulaire à l'identifiant :texte utilisé dans la requête (veuillez noter l'utilisation des ":" dans la requête). $texte_formulaire doit être passé à la fonction par référence. C'est pour cela qu'on utilise &$texte_formulaire. Le dernier argument de OCIBindByName est la longueur maximale que l'argument :texte peut prendre. Si on met -1, PHP utilisera la longueur de $texte_formulaire.

Cette fonction s'utilise toujours avant OCIExecute et après OCIParse.

Cette fonction sert aussi à passer les arguments des procédures stockées, comme nous l'avons vu précédemment.

Terminer une requête

Lorsqu'on a finit d'utiliser un résultat de requête, il est préférable de libérer les ressources allouées avec la fonction OCIFreeStatement :

$stmt = OCIParse($connexion, "SELECT * FROM table");
OCIExecute($stmt);
...
OCIFreeStatement($stmt);

// On coupe la connexion au serveur Oracle
OCILogOff($connexion);

On ferme la connexion au serveur Oracle avec la fonction OCILogOff.

Fonctions utiles

nom description
OCILogOn sert à se connecter au serveur Oracle
OCIParse prépare l'exécution d'une requête
OCIExecute effectue la requête SQL préparée avec OCIParse
OCIFetch récupère une ligne de résultat
OCIFetchInto récupère une ligne de résultat dans un tableau
OCIResult récupère la valeur d'une colonne dans une ligne lue par OCIFetch
OCIBindByName associe une variable PHP avec une variable PL/SQL
OCIFreeStatement libère les ressources utilisée par une requête donnée
OCIRowCount donne le nombre de lignes affectées par commande de modification (UPDATE ou INSERT, mais pas SELECT)
OCILogOff ferme la connexion au serveur

Référence

La section OCI8 du site php.net


format imprimable format imprimable



Copyright © 2000-2006 themanualpage.org - Ce site est soumis aux conditions décrites dans les licences GNU GPL et FDL.