Developpez.com - 4D
X

Choisissez d'abord la catégorieensuite la rubrique :


Introduction aux OCI

Date de publication : Juin 2004

Par Noreddine Margoum (Technicien Contrôle et Qualité)
 

Le propos de cette note technique est de fournir une introduction nécessaire à l’utilisation des OCI, et plus particulièrement de l’implémentation par 4D des OCI, avec le plug-in 4D For OCI. La seule documentation actuellement disponible, en anglais, est la documentation Oracle. Ce qui peut, nous semble-t-il, rebuter un développeur qui aborde le sujet. Nous proposons donc de décrire l’ossature d’un programme utilisant les OCI, avec un exemple d’implémentation de chaque partie de sa structure.

I. Qu’est que OCI ?
II. Structure générale d’une application OCI
III. La notion de Handle
IV. Mise en oeuvre du plug-in 4D For OCI
Initialisation de l’environnement et allocations
Préparation et exécution des requêtes SQL
SELECT
INSERT
UPDATE
DELETE
Fermeture de la connexion et libération des handles
V. Utilisation de la base de test OCI
VI. Conclusion
VII. Base exemple


I. Qu’est que OCI ?

OCI (Oracle Call Interface) est une librairie dynamique fournissant, à travers un ensemble de fonctions, la possibilité d’un contrôle quasi-total à distance d’une base de données Oracle.
Les commandes se situent donc à un niveau très bas, ce qui entraîne leur complexité.

Parmi les possibilités de OCI, il existe :

   · Le support de SQL dynamique ;
   · La manipulation (insertion…) des données par tableaux ;
   · Manipulation des objets (types définis par l’utilisateur, type collection…) et de méta-données…


II. Structure générale d’une application OCI

La structure générale d’un programme ou application qui utilise les OCI se présente sous la forme suivante :

  1. Initialisation de l’environnement de programmation ;

  2. Allocation des différents handles, représentés sous la forme d’entiers longs dans 4D, et permettant de se connecter au serveur Oracle et de définir la session de l’utilisateur ;

  3. Préparation des requêtes SQL à exécuter ;

  4. Exécution des requêtes SQL ;

  5. Fermeture de la session utilisateur et déconnexion du serveur ;

  6. Libération des handles alloués.

Nous allons illustrer, un peu plus loin dans ce document, chacune des étapes de cette structure, en l’implémentant avec le plug-in 4D For OCI.


III. La notion de Handle

Un handle est un pointeur sur une zone memoire allouee par la librairie OCI. Dans 4D, un handle est un entier long, qui doit imperativement etre alloue.
La manipulation (lecture/ecriture) des informations vehiculees par ces handles se fait par les commandes OCIAttrGet(), pour la lecture, et OCIAttrSet(), pour l'écriture.
Il existe plusieurs types de handles structures hierarchiquement et dépendant les uns des autres. Nous allons enumerer les principaux d'entre eux, notamment ceux que nous allons utiliser dans nos exemples ; pour les autres handles, Il faudra consulter la documentation OCI fournie par Oracle.


La hierarchie des handles se presente donc ainsi, du plus eleve au plus bas :


A - Le handle-environnement (environment handle). Toute allocation d'un autre type de handle lui est assujettie. C'est donc le premier handle alloue. Il est alloue par la commande speciale OCIEnvCreate(). Ce handle definit le contexte dans lequel les commandes OCI vont etre appelees. Par exemple, la manipulation d'objets comme les Collections ou les tables imbriquees ("nested tables"), ne sont possibles que dans l'environnement OCI_OBJECT.


B - Un handle-contexte (service context handle) qui determine le contexte operationnel et auquel sont associes les handles suivants :

  • un handle-serveur (server handle) qui identifie la source de donnees Oracle ;

  • un handle-session (user session handle) qui definit l'acces de l'utilisateur ;

  • un handle-transaction qui definit la transaction dans laquelle se deroulent la ou les requetes SQL ;

  • un handle-requete (statement handle) qui definit la requete SQL. Ce handle doit etre alloue. Les handles suivants lui sont associes :

    a - un handle-define (define handle) qui recouvre les variables de sortie. En d'autres termes, ce handle sert pour les requetes de type SELECT, a recuperer les donnees de la table Oracle dans 4D (sortie dans 4D). Ce handle est automatiquement alloue dans 4D For OCI.

    b - un handle-bind (bind handle) qui recouvre les variables en entree. En d'autres termes, ce handle sert pour les requetes de type INSERT, UPDATE et DELETE, a ajouter, modifier ou supprimer des donnees dans Oracle, a partir de donnees provenant de 4D (entree dans Oracle). Ce handle est automatiquement alloue dans 4D For OCI.

Il est important de comprendre que les handles serveur, session et transaction sont eux-meme traites comme des attributs du handle-contexte. Il en va de meme pour les handles define et bind vis-a-vis du handle-requete.

Il existe aussi un handle-erreur. Ce handle sort de la hierarchie, dans la mesure ou tout appel a une commande OCI, necessite la verification de ce handle.

Le point fort des handles est qu'ils evitent le recours a une multitude de variables, chacune manipulant une information particuliere. Pour ce faire, les handles pointent des zones de stockage d'informations. Ces informations sont retrouvees une a une en lisant un a un les attributs du handle.


IV. Mise en oeuvre du plug-in 4D For OCI

Nous allons maintenant mettre en oeuvre avec le plug-in 4D For OCI, les étapes présentées pour la structure générale d’un programme OCI.


Initialisation de l’environnement et allocations

Ici, on reprend les étapes 1 (Initialisation de l’environnement) et 2 (allocation des handles) de la structure du programme OCI.

Il s’agit d’une méthode 4D permettant à un utilisateur de se connecter à la base Oracle. Afin de ne pas alourdir le code, nous avons omis la gestion des éventuelles erreurs. Ce code peut paraître long pour une simple connexion. Il faut savoir que le plug-in 4D For OCI fournit une méthode de connexion simple OCILogon(), ce qui évite beaucoup d’allocations de handles…et raccourcit sensiblement le code. L’intérêt de ce code est donc avant tout didactique.

La méthode commence par allouer les différents handles, dans l’ordre de la hiérarchie, telle que décrite plus haut, du sommet vers la base. Tous les handles sont alloués par rapport au handle maître, le handle-environnement.

OCIServerAttach() crée un accès au serveur Oracle, en associant la chaîne de connexion au handle-serveur.
OCISessionBegin() démarre la session proprement dite, en établissant la connexion.


Code source de la méthode projet OCI_CONNECTER :


   `Méthode : CONNECTER
   `Exemple d'Appel de la méthode : CONNECTER ("SCOTT";"TIGER";"ORAQA")
   `usage : permet de connecter un utilisateur à une base Oracle
   `$1 : nom de l'utilisateur
   `$2 : mot de passe
   `$3 : chaîne de connexion ou nom du service oracle définis dans le fichier 'tnsnames.ora'

C_ALPHA(255;${1})
C_ENTIER LONG(envhp) `handle de l'environnement
C_ENTIER LONG(svchp) `handle-contexte
C_ENTIER LONG(authp) `handle-session
C_ENTIER LONG(srvhp) `handle-serveur
C_ENTIER LONG($status) `retour des commandes OCI

   ` Allocations des handles
$status:=OCIEnvCreate (envhp;OCI_DEFAULT) `handle d'environnement. Environnment 'Défaut'

   `(Pas de traitement d'objets...)
$status:=OCIHandleAlloc (envhp;errhp;OCI_HTYPE_ERROR ) `handle sur les erreurs éventuelles
$status:=OCIHandleAlloc (envhp;svchp;OCI_HTYPE_SVCCTX ) `handle-contexte
$status:=OCIHandleAlloc (envhp;authp;OCI_HTYPE_SESSION ) `handle-session
$status:=OCIHandleAlloc (envhp;srvhp;OCI_HTYPE_SERVER ) `handle-serveur

   `création d'un accès au serveur en affectant la chaîne de connexion au handle du serveur
$status:=OCIServerAttach (srvhp;errhp;$3)

   `affectation du handle-serveur au handle-contexte
$status:=OCIAttrSetVal (svchp;srvhp;OCI_ATTR_SERVER ;errhp)

   `mise à jour des attributs nom et mot de passe du handle-session
   `avec les paramètres fournis à cette méthode
$status:=OCIAttrSetText (authp;$1;OCI_ATTR_USERNAME ;errhp)
$status:=OCIAttrSetText (authp;$2;OCI_ATTR_PASSWORD ;errhp)

   `affectation du handle-session au handle-contexte
$status:=OCIAttrSetVal (svchp;authp;OCI_ATTR_SESSION ;errhp)

   `démarrage de la session utilisateur
$status:=OCISessionBegin (svchp;errhp;authp;OCI_CRED_RDBMS ;OCI_DEFAULT )


Préparation et exécution des requêtes SQL

Ici, on reprend les étapes 3 (préparation de la requête SQL) et 4 (exécution de la requête SQL) de la structure du programme OCI. On va fournir 4 méthodes, chacune implémentant une requête SQL fondamentale (SELECT, INSERT, UPDATE, DELETE).


SELECT

La méthode ci-après permet de récupérer les valeurs des colonnes de la table Oracle "emp", table des employés, en exécutant la requête SQL SELECT.
La méthode commence par allouer un handle pour la requête SQL (handle-requête).
Cette allocation est typique de chaque méthode qui travaille sur les requêtes (INSERT, UPDATE, DELETE).
La méthode sélectionne tous les employés mais uniquement certaines colonnes (champs).
Ici on sélectionne le numéro d’employé (empno), le nom (ename), son métier (job) et la date d’embauche (hiredate).
Une fois définis et initialisés le libellé de la requête SQL et le handle-requête, ils sont mis en relation par la commande OCIStmtPrepare().
Pour chaque colonne impliquée dans la requête SQL, nous associons un tableau 4D pour récupérer l’ensemble des valeurs. Pour mettre en relation le tableau 4D et la colonne Oracle visée, on utilise la commande OCIDefineByPos().
Cette commande attend le numéro de la colonne mentionnée dans la requête SQL.
Le type Date étant particulier dans Oracle, puisqu’il est composé d’une partie date et d’une partie heure, nous avons utilisé ici la même commande OCIDefineByPos().
En fait, cette possibilité a été utilisée ici, car la composante heure ne nous intéresse pas.
Dans le cas contraire, nous aurions été obligé d’utiliser la commande OCIDefineDateByPos().


Code source de la méthode projet OCI_SELECT :


C_TEXTE($requete_sql) `libellé de la requête SQL

C_ENTIER LONG($status) `code retour des commandes OCI
C_ENTIER LONG($errhp) `handle-erreur
C_ENTIER LONG($stmthp) `handl- requête
C_ENTIER LONG($define) `handle-define

   `informations à récupérer de la table Oracle nommée 'emp'
C_ENTIER LONG($numero_colonne) `numéro de la colonne à récupérer après exécution de la requête SQL
TABLEAU ENTIER LONG(tls_empno;20) `numéros d'employés (colonne 'empno')
TABLEAU ALPHA(255;tas_ename;20) `noms d'employés (colonne 'ename' de la table 'emp')
TABLEAU ALPHA(255;tas_job;20) `métiers des employés (colonne 'job' de la table 'emp')
TABLEAU DATE(tds_hiredate;20) `dates d'embauche (colonne 'hiredate' de la table 'emp')
C_ENTIER LONG($max_emp) `nombre maximum d'employés à récupérer
C_ENTIER LONG(null_ind1;null_ind2;null_ind3) `variables indicateurs

   `requête-sélection de la liste des numéros, noms, métiers et dates d'embauche de tous les employés de
   `la table oracle ‘emp’
$requete_sql:="SELECT empno, ename, job,hiredate FROM emp"

   `allocation du handle-requête. Le handle-environnement envhp
   `a été alloué dans la méthode de connexion OCI_CONNECTER
$status:=OCIHandleAlloc (envhp;$stmthp;OCI_HTYPE_STMT )

   `allocation du handle-erreur
$status:=OCIHandleAlloc (envhp;$errhp;OCI_HTYPE_ERROR )

   `affectation du libellé de la requête SQL au handle-requête
$status:=OCIStmtPrepare ($stmthp;$errhp;$requete_sql;OCI_DEFAULT )

   `variables-indicateurs pour la commande OCIDefineByPos().
   `Les informations retournées par ces variables sont inutiles dans notre exemple
   `ces variables servent notamment à savoir s'il y a des valeurs NULL, tronquées.
null_ind1:=0
null_ind2:=0
null_ind3:=0

   `réalisation du Define pour chaque colonne définie dans la requête SQL
   `On notera que $define, qui définit le handle-define, n'a pas nécessité d'être explicitement alloué.

$numero_colonne:=1 `numéro de colonne pointée, remontée par l'exécution de la requête (empno)
$status:=OCIDefineByPos ($stmthp;$define;$errhp;$numero_colonne;->tls_empno;SQLT_INT ;
   ->null_ind1;->null_ind2;->null_ind3;OCI_DEFAULT )

$numero_colonne:=2 `numéro de colonne pointée, remontée par l'exécution de la requête (ename)
$status:=OCIDefineByPos ($stmthp;$define;$errhp;$numero_colonne;->tas_ename;SQLT_STR ;
   ->null_ind1;->null_ind2;->null_ind3;OCI_DEFAULT )

$numero_colonne:=3 `numéro de colonne pointée, remontée par l'exécution de la requête (job)
$status:=OCIDefineByPos ($stmthp;$define;$errhp;$numero_colonne;->tas_job;SQLT_STR ;
   ->null_ind1;->null_ind2;->null_ind3;OCI_DEFAULT )

$numero_colonne:=4 `numéro de colonne pointée, remontée par l'exécution de la requête (hiredate)
$status:=OCIDefineByPos ($stmthp;$define;$errhp;$numero_colonne;->tds_hiredate;SQLT_ODT ;
   ->null_ind1;->null_ind2;->null_ind3;OCI_DEFAULT )

   `récupération des employés à concurrence de 20 enregistrements
$max_emp:=20

   `exécution de la requête SQL
$status:=OCIStmtExecute (svchp;$stmthp;$errhp;$max_emp;0;0;0;OCI_DEFAULT )

   `libération du handle-requête
$status:=OCIHandleFree ($stmthp)

   `libération du handle-erreur
$status:=OCIHandleFree ($errhp)


INSERT

La méthode ci-après permet d’ajouter des enregistrements dans la table Oracle "emp", en exécutant la requête SQL INSERT.
L’ensemble des valeurs que l’on va ajouter est stocké dans des tableaux 4D. On associe les données à ajouter avec les colonnes Oracle, en utilisant dans la requête SQL le caractère ":". Ce marquage peut être utilisé ensuite de 2 manières : l’association données 4D/colonnes Oracle est faite soit par position (commande OCIBindByPos()) ou par nom (commande OCIBindByName()).

info A noter que pour l’insertion de valeurs de type date, on utilise la commande OCIBindDateByPos(). Cette commande attend le passage de variables de types date et heure, afin de représenter intégralement le type Oracle ODT (Object Date Time) qui contient les 2 parties date et heure. La partie heure ne nous intéressant pas, nous avons utilisé une variable heure 4D avec une valeur nulle.

Code source de la méthode projet OCI_INSERT :


C_TEXTE($requete_sql) `libellé de la requête SQL

C_ENTIER LONG($status) `code retour des fonctions OCI
C_ENTIER LONG($errhp) `handle-erreur
C_ENTIER LONG($stmthp) `handle-requête
C_ENTIER LONG($bind) `handle-bind

C_POINTEUR(pnull_ind1;pnull_ind2;pnull_ind3) `variables indicateurs (voir la méthode `OCI_SELECT)

C_ENTIER LONG($nb_emp) `nombre d'employés à insérer

   `déclaration des données à insérer
TABLEAU ENTIER LONG(tli_empno;3) `colonne empno
TABLEAU ALPHA(255;tai_ename;3) `colonne ename
TABLEAU ALPHA(255;tai_job;3) `colonne job
TABLEAU ENTIER LONG(tli_mgr;3) `colonne mgr
TABLEAU DATE(tdi_hiredate;3) `colonne hiredate
C_HEURE(null_time) `variable de type heure, en complément de la colonne date, pour représenter

   `intégralement le type ODT oracle, qui comprend la date et l’heure
TABLEAU ENTIER LONG(tli_sal;3) `colonne sal
TABLEAU ENTIER LONG(tli_comm;3) `colonne comm
TABLEAU ENTIER LONG(tli_deptno;3) `colonne deptno

   `remplissage des données à insérer
`colonne empno
tli_empno{1}:=1111
tli_empno{2}:=2222
tli_empno{3}:=3333
   `colonne ename
tai_ename{1}:="Joel"
tai_ename{2}:="Catherine"
tai_ename{3}:="Marianne"
   `colonne job
tai_job{1}:="analyste"
tai_job{2}:="vendeur"
tai_job{3}:="manager"
   `colonne mgr
tli_mgr{1}:=7902
tli_mgr{2}:=7698
tli_mgr{3}:=7788
   `colonne hiredate
tdi_hiredate{1}:=!01/01/03!
tdi_hiredate{2}:=!02/01/03!
tdi_hiredate{3}:=!03/01/03!
null_time:=?00:00:00?
   `colonne sal
tli_sal{1}:=1915
tli_sal{2}:=2012
tli_sal{3}:=1713
   `colonne comm
tli_comm{1}:=100
tli_comm{2}:=200
tli_comm{3}:=150
   `colonne deptno
tli_deptno{1}:=20
tli_deptno{2}:=30
tli_deptno{3}:=20

   `requête SQL d'insertion des données. On précise les colonnes de la table 'emp', qui seront remplies
   `noter l'utilisation du caractère ":" pour indiquer qu'une variable fournira les données à insérer
   `cette indication sera exploitée soit par nom (nom de la variable 4D) soit par position (numéro de
   `position dans la requête).
$requete_sql:="INSERT INTO emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)"
$requete_sql:=$requete_sql+" VALUES (:tli_empno, :tai_ename, :tai_job, :tli_mgr,"
$requete_sql:=$requete_sql+" :tdi_hiredate, :tli_sal,:tli_comm,:tli_deptno)"

   `allocation du handle-requête
$status:=OCIHandleAlloc (envhp;$stmthp;OCI_HTYPE_STMT )

   `allocation du handle erreur
$status:=OCIHandleAlloc (envhp;$errhp;OCI_HTYPE_ERROR )

   `affectation du libellé de la requête SQL au handle requête
$status:=OCIStmtPrepare ($stmthp;$errhp;$requete_sql;OCI_DEFAULT )

   `réalisation du bind pour chaque colonne de la requête. Le bind est effectué par position
   `remarquez que le handle-bind $bind n'a pu à être explicitement alloué
$status:=OCIBindByPos ($stmthp;$bind;$errhp;1;->tli_empno;SQLT_INT ;
   pnull_ind1;pnull_ind2;pnull_ind3;OCI_DEFAULT ;BIND_IN )
$status:=OCIBindByPos ($stmthp;$bind;$errhp;2;->tai_ename;SQLT_STR ;
   pnull_ind1;pnull_ind2;pnull_ind3;OCI_DEFAULT ;BIND_IN )
$status:=OCIBindByPos ($stmthp;$bind;$errhp;3;->tai_job;SQLT_STR ;
   pnull_ind1;pnull_ind2;pnull_ind3;OCI_DEFAULT ;BIND_IN )
$status:=OCIBindByPos ($stmthp;$bind;$errhp;4;->tli_mgr;SQLT_INT ;
   pnull_ind1;pnull_ind2;pnull_ind3;OCI_DEFAULT ;BIND_IN )

   `le type Oracle ODT recouvre à la fois la date et l'heure
   `comme la valeur de l'heure ne nous intéresse pas ici, celle-ci est donc passée comme nulle
$status:=OCIBindDateByPos ($stmthp;$bind;$errhp;5;->null_time;->tdi_hiredate;SQLT_ODT ;
   pnull_ind1;pnull_ind2;pnull_ind3;OCI_DEFAULT ;BIND_IN )
$status:=OCIBindByPos ($stmthp;$bind;$errhp;6;->tli_sal;SQLT_INT ;
   pnull_ind1;pnull_ind2;pnull_ind3;OCI_DEFAULT ;BIND_IN )
$status:=OCIBindByPos ($stmthp;$bind;$errhp;7;->tli_comm;SQLT_INT ;
   pnull_ind1;pnull_ind2;pnull_ind3;OCI_DEFAULT ;BIND_IN )
$status:=OCIBindByPos ($stmthp;$bind;$errhp;8;->tli_deptno;SQLT_INT ;
   pnull_ind1;pnull_ind2;pnull_ind3;OCI_DEFAULT ;BIND_IN )

   `nombre d'employés à insérer
$nb_emp:=3

   `exécution de la requête SQL
$status:=OCIStmtExecute (svchp;$stmthp;$errhp;$nb_emp;0;0;0;OCI_DEFAULT )

   `confirmation de l'insertion par validation immédiate de la transaction
   `sinon, l'insertion est effective à la fermeture de la session
status:=OCITransCommit (svchp;$errhp;0)

   `libération du handle-requête
$status:=OCIHandleFree ($stmthp)

   `libération du handle-erreur
$status:=OCIHandleFree ($errhp)


UPDATE

La méthode ci-après permet de mettre à jour les enregistrements précédemment ajoutés dans la table Oracle "emp", en exécutant la requête SQL UPDATE.
Dans cette méthode, nous mettons à jour les 3 enregistrements ajoutés par la requête INSERT. Nous modifions uniquement les noms (colonne ename).

info A remarquer que nous avons fait ici un Bind (association variable 4D/colonne Oracle) par nom. Dans la précédente requête INSERT, nous l’avons fait par position.

Code source de la méthode projet OCI_UPDATE :


C_TEXTE($requete_sql) `libellé de la requête SQL

C_ENTIER LONG($status) `code retour des commandes OCI
C_ENTIER LONG($errhp) `handle-erreur
C_ENTIER LONG($stmthp) `handle-requête
C_ENTIER LONG($bind) `handle-bind

C_POINTEUR(pnull_ind1;pnull_ind2;pnull_ind3) `variables indicateurs (voir la méthode `OCI_SELECT)

C_ENTIER LONG($nb_emp) `nombre d'employés à mettre à jour

   `déclaration des données à modifier
TABLEAU ENTIER LONG(tlu_empno;3) `colonne empno
TABLEAU ALPHA(255;tau_ename;3) `colonne ename

   `critère de recherche dans la requête SQL pour la mise à jour
tlu_empno{1}:=1111
tlu_empno{2}:=2222
tlu_empno{3}:=3333
   `données modifiées
tau_ename{1}:="JJ"
tau_ename{2}:="CC"
tau_ename{3}:="MM"

   `mise à jour des noms des employés de la table oracle emp dont les numéros sont 1111,2222, et 3333
   `rappel : ce sont les données qui ont été insérées qui sont modifiées
$requete_sql:="UPDATE emp SET ename=:les_noms WHERE empno=:les_numeros"

   `allocation du handle-requête
$status:=OCIHandleAlloc (envhp;$stmthp;OCI_HTYPE_STMT )

   `allocation du handle erreur
$status:=OCIHandleAlloc (envhp;$errhp;OCI_HTYPE_ERROR )

   `affectation du libellé de la requête SQL au handle-requête
$status:=OCIStmtPrepare ($stmthp;$errhp;$requete_sql;OCI_DEFAULT )

   `on effectue un Bind par nom. Sur le INSERT, on l'a effectué par position
$status:=OCIBindByName ($stmthp;$bind;$errhp;":les_noms";->tau_ename;SQLT_STR ;
pnull_ind1;pnull_ind2;pnull_ind3;OCI_DEFAULT ;BIND_IN )
$status:=OCIBindByName ($stmthp;$bind;$errhp;":les_numeros";->tlu_empno;SQLT_INT ;
pnull_ind1;pnull_ind2;pnull_ind3;OCI_DEFAULT ;BIND_IN )

   `exécution de la requête SQL
$nb_emp:=3
$status:=OCIStmtExecute (svchp;$stmthp;$errhp;$nb_emp;0;0;0;OCI_DEFAULT )

   `confirmation de la modification par validation immédiate de la transaction
   `sinon, la mise à jour est effective à la fermeture de la session
status:=OCITransCommit (svchp;$errhp;0)

   `libération du handle-requête
$status:=OCIHandleFree ($stmthp)

   `libération du handle-erreur
$status:=OCIHandleFree ($errhp)


DELETE

La méthode ci-après permet de supprimer les enregistrements précédemment ajoutés dans la table Oracle "emp", en exécutant la requête SQL DELETE.
Ici, nous supprimons les enregistrements que nous avons précédemment insérés et mis à jour. Le code de cette méthode est à rapprocher de la requête UPDATE, dans la mesure où nous effectuons aussi un Bind (association variable 4D/colonne Oracle) par nom.


Code source de la méthode projet OCI_DELETE :


C_TEXTE($requete_sql) `libellé de la requête SQL

C_ENTIER LONG($status) `code retour des commandes OCI
C_ENTIER LONG($errhp) `handle-erreur
C_ENTIER LONG($stmthp) `handle-requête
C_ENTIER LONG($bind) `handle-bind

C_POINTEUR(pnull_ind1;pnull_ind2;pnull_ind3) `variables indicateurs (voir la méthode `OCI_SELECT)

C_ENTIER LONG($nb_emp) `nombre d'employés à supprimer dans la base Oracle
TABLEAU ENTIER LONG(tld_empno;3) `déclaration des données à rechercher pour la suppression

   `les numéros des enregistrements des employés à supprimer de la base Oracle
tld_empno{1}:=1111
tld_empno{2}:=2222
tld_empno{3}:=3333

   `suppression des employés de la table oracle emp dont les numéros sont 1111,2222, et 3333
   `ces employés ont été ajoutés par la méthode OCI_INSERT
$requete_sql:="DELETE FROM emp WHERE empno=:numemp"

   `allocation du handle requête
$status:=OCIHandleAlloc (envhp;$stmthp;OCI_HTYPE_STMT )

   `allocation du handle erreur
$status:=OCIHandleAlloc (envhp;$errhp;OCI_HTYPE_ERROR )

   `affectation du libellé de la requête SQL au handle-requête
$status:=OCIStmtPrepare ($stmthp;$errhp;$requete_sql;OCI_DEFAULT )

`on effectue un Bind par nom.
`remarquez que le handle-bind $bind n'a pas nécessité d'être explicitement alloué
$status:=OCIBindByName ($stmthp;$bind;$errhp;":numemp";->tld_empno;SQLT_INT ;
   pnull_ind1;pnull_ind2;pnull_ind3;OCI_DEFAULT ;BIND_IN )

   `exécution de la requête SQL
$nb_emp:=3
$status:=OCIStmtExecute (svchp;$stmthp;$errhp;$nb_emp;0;0;0;OCI_DEFAULT )

   `confirmation de la suppression par validation immédiate de la transaction
   `sinon, la suppression est effective à la fermeture de la session
$status:=OCITransCommit (svchp;$errhp;0)

   `libération du handle-requête
$status:=OCIHandleFree ($stmthp)

   `libération du handle-erreur
$status:=OCIHandleFree ($errhp)


Fermeture de la connexion et libération des handles

Ici, on reprend les étapes 5 (fermeture de la session) et 6 (libération des handles) de la structure du programme OCI.
C’est la fonction OCIHandleFree() qui est utilisée. Les handles étant structurés hiérarchiquement, la libération d’un handle-père entraîne celle des handles-fils.

La méthode ci-après montre le code pour se déconnecter du serveur Oracle. On aurait pu plus simplement utiliser la méthode OCILogoff() en lieu et place de ce code.

OCISessionEnd() supprime la session.
OCIServerDetach() supprime le chemin d’accès au serveur oracle.

On peut, après cela, libérer un à un les handles, ou alors libérer le handle environnement, ce qui entraînera la libération des autres handles.


Code source de la méthode projet OCI_DECONNECTER :


   `Méthode : DECONNECTER
   `Appel de la méthode : DECONNECTER
   `usage : permet de déconnecter l'utilisateur couramment connecté

C_ENTIER LONG($status) `retour des commandes OCI

$status:=OCISessionEnd (svchp;errhp;authp) `suppression de la session utilisateur
$status:=OCIServerDetach (srvhp;errhp) `suppression de l'accès à la source de données
$status:=OCIHandleFree (envhp) `libérer le handle-environnement qui libérera automatiquement à
`son tour les autres handles


   `On aurait pu aussi utiliser la commande OCICleanUp() à la place de OCIHandleFree,
   `pour libérer d'un coup tous les handles alloués
   `status:=OCICleanUp ()


V. Utilisation de la base de test OCI

Afin d'utiliser la base de test, il faut impérativement que les conditions suivantes soient réunies :

  • sur Windows, il faut avoir installé la partie cliente d'Oracle, fournie sur le CD-Rom ou le site web d'Oracle ;

  • sur Mac OS X, il faut suivre les instructions fournies dans le "Readme" fourni avec le produit, notamment :

    1. Copier dans /private/etc/ votre fichier 'tnsnames.ora' , mis à jour avec vos propres paramètres (nom de service, adresse IP de la base Oracle) pour localiser votre base Oracle, et attribuer le droit de lecture sur le fichier.

      Par exemple, en utilisant le Terminal de OS X, on saisira :

      sudo cp /chemin d'accès à votre fichier tnsnames.ora /private/etc/tnsnames.ora
      sudo chmod 777 /private/etc/tnsnames.ora

      La première ligne de commande saisie dans le terminal d'OS X sert à copier le fichier en prenant temporairement la 'casquette' (profil) du root. Le mot de passe root vous sera demandé.
      La deuxième ligne de commande sert à attribuer tous les droits pour tout le monde.

      Si vous avez des problèmes pour la saisie des chemins d'accès au fichier à copier, une astuce consiste à faire glisser le fichier sur la fenêtre du Terminal.
      Le chemin d'accès du fichier y apparaît alors.

    2. Dans le dossier 'Oracle items' fourni en téléchargement avec le plug-in 4D For OCI, on trouvera la dll 'libcIntsh.dylib'.

      Il faudra copier cette dll dans /usr/lib et donner les droits de lecture et exécution sur cette librairie :

      sudo cp /chemin d'accès à votre fichier libcIntsh.dylib /usr/lib/
      sudo chmod 555 /usr/lib/libcIntsh.dylib

    3. La première ligne sert à copier la DLL, la seconde à attribuer les droits de lecture et exécution pour tout le monde.

La base de test des OCI fournie avec cette note technique, utilisable avec une version de 4D 2003 ou supérieure, reprend les codes sources expliqués dans la présente note. Il faudra bien veiller à changer vos paramètres de connexion fournis à la méthode projet OCI_CONNECTER().

Cette base ayant un but uniquement didactique, il faudra bien suivre les pages du dialogue de démonstration dans l’ordre, notamment l’ordre insertion des données, mise à jour des données et suppression des donnés.

En mode Menus Créés, il faut choisir le menu \Fichier\Demo… et vous laisser guider.


VI. Conclusion

Cette note vous a donné un aperçu de l’utilisation du plug-in 4D For OCI, en présentant des exemples d’utilisation des quatre types fondamentaux de requêtes SQL (SELECT, INSERT, UPDATE, DELETE) ainsi qu’un exemple de connexion/déconnexion à une base Oracle. Nous espérons que cette note vous a donné envie d’explorer plus avant l’utilisation du plug-in 4D For OCI, en exploitant par exemple, le fonctionnement de l’environnement Objet, qui est sans aucun doute original et puissant.


VII. Base exemple

Téléchargez la base exemple :

Base pour Windows

Base pour Mac Os

__________________________________________________
Copyright © 1985-2009 4D SA - Tous droits réservés
Tous les efforts ont été faits pour que le contenu de cette note technique présente le maximum de fiabilité possible.
Néanmoins, les différents éléments composant cette note technique, et le cas échéant, le code, sont fournis sans garantie d'aucune sorte. L'auteur et 4D S.A. déclinent donc toute responsabilité quant à l'utilisation qui pourrait être faite de ces éléments, tant à l'égard de leurs utilisateurs que des tiers.
Les informations contenues dans ce document peuvent faire l'objet de modifications sans préavis et ne sauraient en aucune manière engager 4D SA. La fourniture du logiciel décrit dans ce document est régie par un octroi de licence dont les termes sont précisés par ailleurs dans la licence électronique figurant sur le support du Logiciel et de la Documentation afférente. Le logiciel et sa documentation ne peuvent être utilisés, copiés ou reproduits sur quelque support que ce soit et de quelque manière que ce soit, que conformément aux termes de cette licence.
Aucune partie de ce document ne peut être reproduite ou recopiée de quelque manière que ce soit, électronique ou mécanique, y compris par photocopie, enregistrement, archivage ou tout autre procédé de stockage, de traitement et de récupération d'informations, pour d'autres buts que l'usage personnel de l'acheteur, et ce exclusivement aux conditions contractuelles, sans la permission explicite de 4D SA.
4D, 4D Calc, 4D Draw, 4D Write, 4D Insider, 4ème Dimension ®, 4D Server, 4D Compiler ainsi que les logos 4e Dimension, sont des marques enregistrées de 4D SA.
Windows,Windows NT,Win 32s et Microsoft sont des marques enregistrées de Microsoft Corporation.
Apple, Macintosh, Power Macintosh, LaserWriter, ImageWriter, QuickTime sont des marques enregistrées ou des noms commerciaux de Apple Computer,Inc.
Mac2Win Software Copyright © 1990-2002 est un produit de Altura Software,Inc.
4D Write contient des éléments de "MacLink Plus file translation", un produit de DataViz, Inc,55 Corporate drive,Trumbull,CT,USA.
XTND Copyright 1992-2002 © 4D SA. Tous droits réservés.
XTND Technology Copyright 1989-2002 © Claris Corporation.. Tous droits réservés ACROBAT © Copyright 1987-2002, Secret Commercial Adobe Systems Inc.Tous droits réservés. ACROBAT est une marque enregistrée d'Adobe Systems Inc.
Tous les autres noms de produits ou appellations sont des marques déposées ou des noms commerciaux appartenant à leurs propriétaires respectifs.
__________________________________________________
 



Valid XHTML 1.1!Valid CSS!

Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
Contacter le responsable de la rubrique 4D