Interface langage hôte PRO*C

Slides:



Advertisements
Présentations similaires
Premier programme en C :
Advertisements

La boucle for : init7.c et init71.c
PL/SQL : Le Langage PL/SQL est une extension du SQL, qui offre
Rappels C.
Vues.
TRANSACTION Problèmes posés
C.
! 1 CREATION D'UNE MAQUETTE EXPORT / IMPORT
PHP mySQL Extension php_mysql. Connexion à une base de données Établir une connexion mysql_connect(string server, string username, string password) –permet.
TP 3-4 BD21.
Programmation dapplication INT. 2 Bases de Données Plan du document Contexteslide 1 Programmer avec une BDslide 2 Client-Serveur SQL et architecture 3.
Programme Introduction aux BD et aux SGBD Le modèle relationnel
1 ARCHITECTURE DACCÈS la méthode générale modèle de données définitions module daccès / modules métiers construction des modèles les modules daccès, les.
Cours 7 - Les pointeurs, l'allocation dynamique, les listes chaînées
L’utilisation des bases de données
Récursivité.
Les méthodes en java Une méthode est un regroupement d’instructions ayant pour but de faire un traitement bien précis. Une méthode pour être utilisée.
RESUMES Module II1 SOMMAIRE CYCLE 1 : Saisir – Afficher – Données
Connexion en mode application. Bases de données - Yann Loyer2 Connexion en mode application Pour tout type dutilisateurs : –passif, actif, gérant Permettre.
T ECHNOLOGIES O RACLE Manipulation des données © sebvita.com.
Les instructions PHP pour l'accès à une base de données MySql
TRANSACTION : confirmation, annulation. transactions : début transactionSET TRANSACTION SAVEPOINT annulerROLLBACK fin transactionCOMMIT.
L’utilisation des bases de données
F Copyright © Oracle Corporation, Tous droits réservés. Créer des programmes avec Procedure Builder.
EPID-CPI-ISAIP Philippe Bancquart - mise à jour 24/02/ page 1 Procédures stockées CPI-SQLServer.
PLSQL ORACLE 8i Connecter VB à BD Oracle Les collections Question de révision Les blocs anonymes Les triggers REVISION Par : Joël Huot.
INSCRIPTION AUX ELEMENTS
1 Développement des Applications des Bases de Données Chapitre 6.
PL/SQL Noreddine GHERABI 1.
Christine Bonnet SOURCES : « Samples » dOracle, « Oracle 8 » R. Chapuis PRO*C – C ++
Les transactions.
Le langage C Structures de données
PHP & My SQL.
Le Langage de BLOC PL/SQL
JDBC L'API JDBC est utilisée pour utilisée pour intéragir avec une base de données.
Les Composants de l’architecture Oracle
Chapitre 6.2 Les curseurs Cours SGBD 3A Mme hkimi Jihène
Créer des packages.
Module 12 : Implémentation de procédures stockées.
Un survol du language C.
Surveiller et résoudre le conflit de verrouillage
 Requêtes MySQL en PHP Introduction
Ait Ahmed Madjid Cohen Lior Jaballah Seddik Leborgne Fabien
Manipulation des Données
Classe 1 CSI2572 Autres modificateurs de déclaration de variables: & volatile & register & static & auto & extern & const volatile Indique au compilateur.
Gestion d’accès aux centrales nucléaires françaises
 Formulaires HTML : traiter les entrées utilisateur
Master 1 SIGLIS Intégration des données dans l’entreprise Stéphane Tallard JDBC: Java Database Connectivity Master 1 SIGLIS1JDBC.
21/04/2015© Robert Godin. Tous droits réservés.1 6Gestion des contraintes d’intégrité en SQL n Contrainte d'intégrité statique – respectée pour chacun.
Introduction  Langage propre à Oracle basé sur ADA  Offre une extension procédurale à SQL  PL/SQL permet d’utiliser un sous-ensemble du langage SQL.
Révision du langage PL/SQL
Initiation au web dynamique Licence Professionnelle.
3 Copyright © Oracle Corporation, Tous droits réservés. Créer des fonctions.
Cours n°4M1.ist-ie (S. Sidhom) UE 203 Promo. M1 IST-IE 2006/07 Conception d’un système d'information sur Internet Architecture trois-tiers : technologies.
02/06/2015© Robert Godin. Tous droits réservés.1 5 Interface entre SQL et un programme n SQL incomplet n Défaut d'impédance (impedance mismatch) – modèle.
PL/SQL Présentation.
Le Langage de Contrôle de Données TRIGGERS
Note: Les nombres écrits en gras renvoie à des leçons entières. Symbole %FOUND 6-13 %ISOPEN 6-13 %NOTFOUND 6-13 %ROWCOUNT 6-13 %ROWTYPE 5, 6-17 %TYPE 1-20.
Procédures Stockées Fonctions Paquetages
Les bases de données Séance 8 Jointures.
Le Langage de Manipulation de Données LMD. 2 Les ordres SQL de manipulation INSERT –Insertion (ajout) de ligne(s) dans une table –Utiliser SQL*LOAD pour.
Séance /10/2004 SGBD - Approches & Principes.
Introduction au langage PL/SQL
Les exceptions Une exception est un identificateur PL/SQL détecté pendant la phase d’exécution. Comment est-elle déclenchée ? À la suite d’une erreur.
Le Langage de Manipulation de Données LMD Module 6.
C++ BY AURÉLIEN MODULO MARION. PLAN DES TROIS PRÉSENTATIONS C++ avancé C++ orienté objet Bases de C++
APP-TSWD Apprentissage Par Problèmes Techniques des Sites Web Dynamiques Licence Professionnelle FNEPI Valérie Bellynck, Benjamin Brichet-Billet, Mazen.
1 Initiation aux bases de données et à la programmation événementielle VBA sous ACCESS Cours N° 4 Support de cours rédigé par Bernard COFFIN Université.
Transcription de la présentation:

Interface langage hôte PRO*C

Principe des langages hôtes Le code SQL est encapsulé dans le programme Création d ’un premier programme appelé pré-source contenant le code du langage et le code SQL Appel d ’un pré-compilateur qui traduit les ordres SQL en ordres du langage hôte Compilation, édition de liens (avec les bibliothèques SQL) et création du programme client exécutable Deux types d ’erreur possibles : erreurs SQL lors de l ’étape de pré-compilation (n° de ligne du pré-source) erreurs du langage hôte lors de la compilation (n° de de ligne du source généré)

Création du programme exécutable Editeur prog prog.pc EXEC SQL… EXEC SQL… Pré-compilateur Correction dans .pc Edition de liens prog.c Recherche erreurs Erreurs SQL Bibliothèques printf(…….); prog.o Erreurs C Compilateur

Exemple de programme : connexion et déconnexion à une base locale /* debut.pc PRO*C : CONNEXION ET DECONNEXION */ #include <stdio.h> #include <ctype.h> #include <string.h> EXEC SQL BEGIN DECLARE SECTION; VARCHAR user[20]; VARCHAR pwd[20]; EXEC SQL END DECLARE SECTION; EXEC SQL INCLUDE sqlca.h; Variables hôtes Zone de communication

Exemple de programme (suite) connection() { /* entrée du mot de passe et du nom */ user.len=asks("Entrer votre user : ",user.arr); pwd.len=asks("Entrer votre pwd : ",pwd.arr); /* connection a la base */ EXEC SQL WHENEVER SQLERROR GOTO erreur; EXEC SQL CONNECT :user IDENTIFIED BY :pwd; printf("\n Connexion réussie ......\n"); return(1); erreur : printf("\n Erreur a la connexion .... "); errpt(); return(0); EXEC SQL WHENEVER SQLERROR continue; }

Exemple de programme (suite 2) selection() { /* fonction de selection */ printf("\n Debut de selection ......\n"); } main() { if (connection()) { selection(); sortie(); } else arret(); sortie() { EXEC SQL COMMIT RELEASE; } arret() { EXEC SQL ROLLBACK RELEASE; }

Exemple de programme (fin) int askn(text,variable) char text[]; int *variable; { char s[20]; printf(text); if ( gets(s) == (char *)0 ) return(EOF); *variable = atoi(s); return(1); } int asks(text,variable) char text[],variable[]; { printf(text); return( gets(variable) == (char *)0 ? EOF : strlen(variable) );

Structure d’un programme Le prologue La section DECLARE La section INCLUDE La section CONNECT Le corps Ordres du langage C Ordres SQL EXEC SQL ……….;

Déclaration des variables hôte (variables d’échange) Passages de variables par valeurs entre le programme client et la BD BD  Programme (SELECT …. INTO :v1,:v2 …) Programme  BD (INSERT …. VALUES (:v1,:v2,….)) Correspondance entre types de variables BD NUMBER(n) NUMBER(n,m) CHAR(n) VARCHAR(n) Pseudo type VARCHAR PRO*C int float char

La section DECLARE Présente au début du programme : variables globales Présente dans une fonction : variables locales EXEC SQL BEGIN DECLARE SECTION; int pno; /* un caractère de + pour la fin de chaîne '\0' */ char pidemp[14]; int pdept; float psal; EXEC SQL END DECLARE SECTION;

Le pseudo-type VARCHAR PRO*C permet l’utilisation du type VARCHAR correspondant au VARCHAR de la base Déclaration dans le programme ‘.pc’ Génération dans le programme ‘.c’ EXEC SQL BEGIN DECLARE SECTION; VARCHAR pnomemp[31]; EXEC SQL END DECLARE SECTION; struct { unsigned int len; unsigned char arr[31]; } pnomemp; longueur de la chaîne chaîne elle même

Utilisation des variables VARCHAR BD  PRO*C Bases de données Nom VARCHAR(5); Adresse VARCHAR(10); N°ligne, N°colonne,longueur colonne, valeur colonne ….. Programme pro*c Varchar pnom[6]; Varchar padresse[11]; 1 1 4 Marc 2 8 Toulouse 2 …….. 4 Marc \0 8 Toulouse \0 pnom.len pnom.arr padresse.len padresse.arr pnom.arr[pnom.len]= '\0'; padresse.arr[padresse.len]= '\0';

Utilisation des variables VARCHAR PRO*C  BD Programme pro*c VARCHAR pidemp[6]; Lire pidemp.arr Base de données Idemp VARCHAR(5); pidemp.len=strlen(pidemp.arr); 3 100 \0 3 100

La section INCLUDE EXEC SQL INCLUDE sqlca.h; Inclusion dans le programme ‘.c’ d’une zone de communication SQL Communication Area Cette zone est systématiquement remplie après exécution d’un ordre SQL Son contenu permet de savoir si l’ordre s’est bien passé (correct, warning ou erreur)

La structure SQLCA (début) long sqlcode; /*résultat de l’exécution =0  succès, >0  succès avec un code d’état, <0  erreur */ unsigned short sqlerrml; /*longueur*/ char sqlerrmc[70]; /*message erreur*/ }sqlerrm; long sqlerrd[6]; /* seul sqlerrd[2] est utilisé : nombre de lignes ‘touchées’ par un ordre SQL (UPDATE, INSERT, DELETE) ou ramenées par un SELECT ou des FETCH */

La structure SQLCA (fin) char sqlwarn[8]; /* sqlwarn[0]= 'W'  présence d'un warning sqlwarn[0]= ''  pas de warning sqlwarn[1]= 'W'  valeur tronquée sqlwarn[2]= 'W'  valeur nulle sqlwarn[3]= 'W'  plus de colonnes du select que de variables de réception sqlwarn[4]= 'W'  toutes les lignes sont touchées par DELETE ou UPDATE sqlwarn[5]= 'W'  inutilisé sqlwarn[6]= 'W'  ROLLBACK par Oracle sqlwarn[7]= 'W'  dans le cas d’un verrouillage multi-ligne préventif , une ligne a été modifiée avant la fin complète du verrouillage */

EXEC SQL CONNECT :user IDENTIFIED BY :pwd; La section CONNECT Connexion à un compte d’une base Oracle Connexion à une base locale /*Déclaration de 2 variables d’échange user et pwd remplissage de ces 2 variables par lecture ou affectation dans le programme */ EXEC SQL CONNECT :user IDENTIFIED BY :pwd; /* Plusieurs cas possibles :  connexion réussie  mauvais nom ou mot de passe  base non ouverte …. */

Connexion à une base distante Client - Serveur Déclaration d’une variable base de données Connexion à la base distante avec la chaîne de connexion ou ‘chemin’ définie sur le poste client Tous les ordres SQL sont préfixés : EXEC SQL DECLARE mabase1 DATABASE; EXEC SQL CONNECT :user IDENTIFIED BY :pwd AT mabase1 USING :chemin; /* ou 'nom_du_chemin' */ EXEC SQL AT mabase1 SELECT …… INTO ……;

L’option WHENEVER SQLERROR Si erreur sur une instruction EXEC SQL  débranchement vers un label Penser à arrêter ce débranchement automatique pour les fonctions suivantes EXEC SQL WHENEVER SQLERROR GOTO erreur; EXEC SQL …………………; erreur : Attention à ne pas continuer en séquence EXEC SQL WHENEVER SQLERROR continue;

SELECT MONO-LIGNE WHENEVER NOT FOUND EXEC SQL SELECT ……. INTO variables hôtes WHENEVER NOT FOUND EXEC SQL SELECT nom,salaire INTO :vnom, :vsalaire FROM emp WHERE idemp = :idemplu; EXEC SQL WHENEVER NOT FOUND GOTO nontrouve; EXEC SQL SELECT nom,salaire INTO :vnom, :vsalaire FROM emp WHERE idemp = :idemplu; nontrouve : Attention à ne pas continuer en séquence

SELECT MULTI - LIGNE ‘ CURSEUR ’ Un curseur est une zone mémoire serveur contenant l’ordre de sélection et la ligne courante. Défini par un ‘ déclare ’. Les lignes sélectionnées sont chargées en mémoire sur le serveur à l ’ouverture du curseur au moment de l ’open. Chaque ligne est retournée vers le programme pro*c client avec l ’ordre ‘ fetch ’ en gérant une boucle . Cette boucle est gérée par le WHENEVER NOT FOUND qui se transforme en ‘ LAST ROW RETURNED ’. La zone mémoire et le curseur sont perdues (récupérées) au ‘ close ’ du curseur.

Exemple de gestion d ’un curseur : Affichage des employés d ’un service Déclaration du curseur Entrée du premier id service lu et boucle service Ouverture du curseur : remplissage mémoire Attention : gestion des erreurs sur l ’open EXEC SQL DECLARE c1 CURSOR FOR SELECT nom, salaire FROM emp WHERE idser=:idserlu; idserlu.len=asks("Entrer service : ",idserlu.arr); while(!strcmp(idserlu.arr,"fin") { EXEC SQL OPEN c1;

Exemple d ’un curseur (2) Gestion de la boucle qui ‘ ramène ’ les lignes Boucle Fin de la boucle : récupération place mémoire EXEC SQL WENEVER NOT FOUND GOTO terminé; while(1) { EXEC SQL FETCH c1 INTO :vnom,:vsal; vnom.arr[vnom.len]='\0'; printf( …………….,vnom.arr,vsal); } terminé : EXEC SQL CLOSE c1;

Exemple d ’un curseur (3) Poursuite de la consultation Entrée d ’un id service suivant ou  ’fin’ Penser aussi à gérer les erreurs sur le cursor soit : à l ’ouverture OPEN au FETCH idserlu.len=asks("idser ou fin: ",idserlu.arr); }

Les variables indicatrices de transfert A chaque FETCH, on peut savoir la valeur retournée pose problème A chaque variable hôte, on associe une variable indicatrice de transfert déclarée en  ’short’ Le contenu de cette variable indique l ’état du transfert : 0 --> aucun problème -1 --> valeur NULLE (NULL) >0 --> valeur tronquée

Variables indicatrices : exemple Déclarations des variables hôtes et indicatrices Utilisation dans le programme Il suffit de tester les variables indicatrices EXEC SQL BEGIN DECLARE SECTION; VARCHAR pnomemp[31]; short ipnomemp; float psal; short ipsal; EXEC SQL END DECLARE SECTION; EXEC SQL FETCH c1 INTO :pnomemp:ipnomemp, :psal:ipsal;

Gestion des transactions en pro*c Même principe que pour les transactions en général Deux déconnexions différentes dans un programme EXEC SQL COMMIT RELEASE ; EXEC SQL ROLLBACK RELEASE; Fin d ’une transaction EXEC SQL COMMIT; EXEC SQL ROLLBACK;

Concurrence d ’accès en pro*c Contrôle de partage simultané en respectant l ’intégrité des données Lecture multi-version cohérente au niveau ligne Plusieurs lectures cohérentes Points de confirmation explicites Verrouillages (implicites ou explicites) au niveau ligne

Lecture Multi - Version Deux manières de voir une ressource : Au début d’une consultation d’une table, Oracle génère une vue fixe ou cliché (snapshot) de cette table Ce cliché est conservé soit en mémoire, soit dans des espaces disques appelés ‘rollback segments’ Ces segments sont utilisés pour : Les reprises avec annulation (ROLLBACK) Assurer la cohérence en lecture Même si la consultation dure longtemps et, malgré des modifications, l’utilisateur ‘verra’ le cliché initial

Lecture Multi – Version Exemple EXEC SQL SELECT SUM(solde) INTO pognon FROM comptes; idcpt solde type_compte /*Début transaction*/ EXEC SQL UPDATE comptes SET solde=solde-1000 WHERE idcpt=100; SET solde=solde+1000 WHERE idcpt=200; EXEC SQL COMMIT; 100 12000 cc 200 500 épargne

Lecture Multi – Version (fin) Les transferts n’affectent en rien le calcul de la somme des comptes –> lecture du cliché Aucun verrou n’est posé en consultation et les verrous posés par les modifications n’empêchent pas la consultation : Une consultation ne bloque pas les autres Une consultation ne bloque pas les mises à jour Une mise à jour ne bloque pas les consultations Dans le cas d’une jointure synchronisée ou certaines lignes d’une tables sont lues plusieurs fois  lecture des mêmes valeurs malgré les modifications

Plusieurs lectures cohérentes Consultations multiples : dans un boucle Préciser à Oracle qu’il doit garder le cliché jusqu’à la fin : Le SGBD n’accepte alors que des SELECT COMMIT pour terminer EXEC SQL SET TRANSACTION READ ONLY;

Plusieurs lectures cohérentes Exemple EXEC SQL SET TRANSACTION READ ONLY; Tant_Que (lire code_ufr_lu.arr) EXEC SQL SELECT COUNT(*) INTO :n FROM étudiant WHERE codeufr= :code_ufr_lu; /* Affichage de n */ Fin_Tant_Que EXEC SQL COMMIT;

Points de confirmation explicites Pose de ‘points de sauvegarde’ (savepoint) Découpage d’une transaction par étapes En cas de problème, on ‘défait’ en remontant sur un point de confirmation sans tout défaire Les points sont posés avec la commande Pour défaire, il suffit de préciser le point ou l’on remonte : EXEC SQL SAVEPOINT nom_du_point; EXEC SQL ROLLBACK TO SAVEPOINT nom_du_point;

Points de confirmation explicites Exemple /* Insertions dans client */ EXEC SQL INSERT INTO clients(no,nom,état) VALUES(:num,:nom,:’ACTIF’); …… /* Modifications dans cette table */ EXEC SQL UPDATE clients SET état=:nouvel_état WHERE no=:num; …………… /* Pose d’un point de confirmation */ EXEC SQL SAVEPOINT avant_sup; /Suppressions dans la table clients */ EXEC SQL DELETE FROM clients WHERE état=‘INACTIF’; If (sqlca.sqlerrd[2] < 30 ) {printf("Nombre de lignes supprimées : %d", sqlca.sqlerrd[2]); EXEC SQL COMMIT;} else {printf("Pas de suppression des %d" lignes , EXEC SQL ROLLBACK TO SAVEPOINT avant_sup;

Points de confirmation implicites Versions anciennes d’Oracle : aucun point de confirmation implicite à chaque ordre LMD En cas de problème, Oracle faisait automatiquement le ROLLBACK complet de la transaction ! Aujourd’hui, Oracle pose un point à chaque action, détecte une erreur, le fait savoir à la transaction (SQLCA) qui choisit la suite Attention : le système ne défait plus donc le programmeur doit choisir une stratégie (défaire ou poursuivre)

Verrouillage au niveau ligne Mise à jour globale avec verrouillage implicite Un ordre UPDATE verrouille les lignes ‘touchées’ Libération des verrous au COMMIT Mise à jour ligne par ligne avec verrouillage implicite UPDATE dans une boucle avec libération immédiate Mise à jour par ligne avec verrouillage explicite Verrouillage préventif des lignes AVANT les modifications

Mise à jour globale avec verrouillage implicite L’ordre UPDATE est envoyée à Oracle Fonctionnement : Les lignes sélectionnés sont ‘montées’ en mémoire A la fin du transfert  verrouillage des lignes Modifications en mémoire et re-écriture sur disque Le COMMIT libère les verrous EXEC SQL UPDATE emp SET sal=sal*1.1 WHERE service=‘info’; EXEC SQL COMMIT;

Mise à jour globale (2) : les problèmes Pas d’isolation des transactions au moment du transfert en mémoire D’autres transactions peuvent ‘monter’ des mêmes lignes au même moment Chaque transaction fait alors les modifications sur de fausses données  Voir Concepts : Intégrité d’une BD

Mise à jour par ligne On se sert d’une variable gérée par Oracle contenant l’adresse de la ligne : ROWID Chaque ligne est verrouillée individuellement au moment de l’UPDATE puis libérée par un COMMIT dans la boucle Même inconvénient que tout à l’heure : deux mêmes UPDATE peuvent ‘monter’ une même ligne

Mise à jour par ligne : Exemple EXEC SQL DECLARE CURSOR c1 FOR SELECT nom,salaire,ROWID FROM emp WHERE dept=:dept_lu; /* Lire dept_lu */ EXEC SQL OPEN c1; EXEC SQL WHENEVER NOTFOUND GOTO fin_maj; while(1) { EXEC SQL FETCH c1 INTO :nom,:sal,:id_row; /* Affichage du nom et saisie de l’augmentation */ EXEC SQL UPDATE emp SET salaire=salaire+:aug_lue WHERE ROWID=:id_row; EXEC SQL COMMIT; }

Mise à jour par ligne avec verrouillage global préventif Toutes les lignes sélectionnées sont verrouillées AVANT les mises à jour Tout autre transaction voulant verrouiller les mêmes lignes sera en attente  verrouillage exclusif Le système est averti si une autre transaction a modifié une ligne pas encore verrouillée  sqlwarn[7] = ‘W’ dans sqlca

Verrouillage global préventif : Exemple EXEC SQL DECLARE CURSOR c1 FOR SELECT nom,salaire FROM emp WHERE dept=:dept_lu FOR UPDATE OF salaire; /* Lire dept_lu */ EXEC SQL OPEN c1; EXEC SQL WHENEVER NOTFOUND GOTO fin_maj; while(1) { EXEC SQL FETCH c1 INTO :nom,:sal; /* Affichage du nom et saisie de l’augmentation */ EXEC SQL UPDATE emp SET salaire=salaire+:aug_lue WHERE CURRENT OF c1; } EXEC SQL COMMIT; Option de verrouillage Chargement et verrouillage

Les variables hôtes tableaux Optimisation des performances en Client-Serveur Diminution du nombre de transfert entre Client et Serveur Sens Client  Serveur Une seule requête est envoyée (INSERT ou UPDATE) Les données sont dans un tableau Sens Serveur  Client Les lignes sont retournées par ‘paquet’ et stockées dans des tableaux

INSERT avec lignes groupées Déclaration des variables tableaux Remplissage des tableaux dans le programme client  nombre de lignes saisies (nbl) Envoi de l’ordre au SGBD EXEC SQL BEGIN DECLARE SECTION; int vnuméro[300]; VARCHAR vnom [300] [30]; EXEC SQL END DECLARE SECTION; EXEC SQL FOR :nbl INSERT INTO emp(no,nom) VALUES(:vnuméro,:vnom); nbl lignes envoyées avec un ordre INSERT

UPDATE avec lignes groupées Déclaration des variables tableaux Saisie et remplissage des tableaux dans le programme client  nombre de lignes saisies (nbl) Envoi de l’ordre UPDATE avec les variables tableaux EXEC SQL BEGIN DECLARE SECTION; int videtu[300]; float vnote [300]; EXEC SQL END DECLARE SECTION; EXEC SQL FOR :nbl UPDATE notes SET note=:vnote WHERE idetu=:videtu;

Sélection avec tableaux nombre de lignes connu Le nombre maximum de lignes est connu Si le nombre de ligne dépasse la capacité du tableau  erreur SQL (too many rows …) Le SGBD nous permet de connaître le nombre de lignes retournées avec la variable sqlca.sqlerrd[2] de la variable sqlca On peut donc travailler dans les tableaux EXEC SQL SELECT numéro,nom INTO :numéro,:nom WHERE dept=10; for (i=0; i<sqlca.sqlerrd[2]; i++) { /* affichage des éléments */ }

Sélection avec tableaux nombre de lignes inconnu Utilisation obligatoire d’un curseur Déclaration de tableaux de réception inférieurs au nombre de lignes sélectionnées sans problème Chaque FETCH retourne le nombre de lignes correspondant à la dimension des tableaux de réception Le dernier FETCH active le NOT FOUND Le nombre total de lignes est dans sqlca.sqlerrd[2]

Sélection avec nombre de lignes inconnu Exemple Soit une table emp de 700 lignes et des variables de réception de 300 éléments Le dernier FETCH active le NOT FOUND (last row returned) EXEC SQL DECLARE c1 CURSOR FOR SELECT no,nom,salaire FROM emp; EXEC SQL OPEN c1; EXEC SQL FETCH c1 INTO :vno,:vnom,:vsal; --- sqlerrd[2] = 300 --- sqlerrd[2] = 600 --- sqlerrd[2] = 700

Bloc PL/SQL dans un programme pro*c Programmation des transactions Si tout va bien : COMMIT En cas de problème : EXCEPTION avec ROLLBACK Le bloc PL est transféré vers le SGBD avec les paramètres passées par le programme pro*c Le bloc PL est envoyé vers le noyau SQL et exécuté dans son ensemble EXEC SQL EXECUTE DECLARE BEGIN EXCEPTION END-EXEC

Bloc PL/SQL embarqué : Transfert de comptes /* Programme C : Déclarations des variables Hôtes*/ EXEC SQL BEGIN DECLARE SECTION; int ncd; /* compte à débiter */ int ncc; /* compte à créditer */ float somme; /* somme à transférer */ VARCHAR message[81]; EXEC SQL END DECLARE SECTION; askn("Entrer compte à débiter : ",&ncd); askn("Entrer compte à créditer : ",&ncc); askn("Entrer le montant : ",&somme);

Bloc PL/SQL embarqué (2) /* Début du bloc PL*/ EXEC SQL EXECUTE; -- déclarations des variables du bloc DECLARE ligned comptes%ROWTYPE; lignec comptes%ROWTYPE; BEGIN SELECT * INTO ligned FROM comptes WHERE nc=:ncd FOR UPDATE OF solde; SELECT * INTO lignec FROM comptes WHERE nc=:ncc FOR UPDATE OF solde; -- verrouillage préventif des 2 lignes

Bloc PL/SQL embarqué (3) IF ligned.solde - :somme < ligned.découvert_autorisé THEN RAISE solde_insuffisant; END IF; UPDATE comptes SET solde = solde - :somme WHERE nc=:ncd; UPDATE comptes SET solde = solde + :somme WHERE nc=:ncc; INSERT INTO opérations VALUES (………); message:=‘Transaction réussie’; COMMIT; -- Fin normale de Transaction -- Libération des verrous

Bloc PL/SQL embarqué (4) EXCEPTION WHEN solde_insuffisant THEN ROLLBACK; message :=‘Solde insuffisant’; WHEN OTHERS THEN message :=SUBSTR(SQLCODE,1,80); END; END-EXEC; message.arr[message.len]=‘\0’; printf("%s \n",message.arr); /* Suite du programme pro*c */

Appels de procédures stockées Le bloc PL/SQL devient une procédure stockée Appel de la procédure dans le programme pro*c EXEC SQL EXECUTE BEGIN transfert(:ncd,:ncc,:somme,:message); END; END-EXEC; Nom de la procédure