You are on page 1of 143

SGBD : Langage PL_SQL

ENIS GI2

Faiza Jedidi

1

Plan
Chapitre 1 : Introduction à PL/SQL et Structures de contrôle Chapitre 2 : Interaction avec Oracle et curseurs explicites Chapitre 3 : Gestion des exceptions Chapitre 4 : Les sous programmes, les sous programmes stockés et les packages Chapitre 5 : Declancheurs de BD

2

Plan
Chapitre 1 : Introduction à PL/SQL et Structures de contrôle
‡ ‡ ‡ ‡ Introduction L¶environnement PL/SQL Structure d¶un bloc PL/SQL Types PL/SQL et déclarations

3

Constates.. Structures de contrôle Fonctions intégrés Blocs nommés : sous programmes Procédures et fonctions stockées Blocs imbriqués Package ± ± ± ± Déclencheurs de BD Portabilité Intégration Accroissement des performances 4 .Introduction ‡ PL/SQL? Extension procédurale à SQL ‡ Avantages de PL/SQL ± Développement de programmes modulaires ‡ ‡ ‡ ‡ ‡ ‡ ‡ Déclaration des identifiants : Variables..

L¶environnement PL/SQL ‡ PL/SQL est une technologie employée par Oracle server et par certains outils oracles. soit dans le serveur Oracle. il effectue les opérations suivantes : ± Séparation des ordres SQL et PL/SQL ± Passage des commandes SQL au processeur SQL (SQL Statement Executor) ± Passage des instructions procédurales au processeur d¶instructions procédurales (Procedural Statement Executor) ‡ Moteur PL/SQL dans les outils Certains outils disposent de leur propre moteur PL/SQL (Oracle Forms. Le moteur utilisé dépend d¶où le bloc a été appelé.«) 5 . Les blocs PL/SQL sont analysés et exécutés par le moteur PL/SQL qui peut se trouver soit dans l¶outil. Oracle Report. ‡ Le moteur PL/SQL (PL/SQL engine) Lorsque le moteur PL/SQL reçoit un bloc pour exécution.

Structure d¶un bloc PL/SQL [ DECLARE --déclaration ] BEGIN --statements [EXCEPTION --handlers] END. Optionnelle Corps du bloc : Obligatoire Optionnelle ‡ PL/SQL distingue deux types de blocs : anonymes ou nommés ± Bloc anonyme correspond à une séquence d¶instructions qui s¶exécute à l¶endroit où elle existe ± Bloc nommé est un sous programme : fonctions ou procédure éventuellement paramétrée et pouvant être appelée autant de fois que nécessaire 6 .

--suite END. 3). 7 . --déclaration V_Mess VARCHAR2 (50) BEGIN SELECT Sal INTO V_Sal FROM Chercheur WHERE Chno =1234.Structure d¶un bloc PL/SQL ‡ Exemple DECLARE ± ceci est un bloc anonyme V_Sal NUMBER (9. EXCEPTION WHEN NO_DATA_FOUND THEN --gestion de l¶exception NO_DATA_FOUND V_Mess := µChercheur non trouvé¶.

variables simples ou composites. Ces instructions peuvent être : ± ± ± ± ± Instructions Instructions Instructions Instructions Instructions d¶affectation de contrôle de flux SQL de gestion des curseurs de gestion des erreurs ‡ Section de gestion des exceptions Cette section optionnelle introduite par le mot EXCEPTION est réservée pour le traitement des erreurs qui pourraient se produire durant l¶exécution d¶un programme 8 . curseurs et exceptions utilisateurs. ‡ Section exécutable Cette section obligatoire introduite par le mot clé BEGIN et se terminant par END contient les instructions du programme et la section de gestion des erreurs si présente.Structure d¶un bloc PL/SQL ‡ Section de déclaration Cette section optionnelle introduite par le mot clé DCLARE est l¶unique endroit de déclaration des constantes.

scale)] VARCHAR2 CHAR DATE BOOLEAN Types composés RECORD TABLE 9 .Types PL/SQL et déclarations ‡ Types PL/SQL PL/SQL supporte une variété de type de données utiles pour déclarer des variables et des constantes ± compatibles avec les types Oracle (colonnes de tables)+type BOOLEAN Type Scalaire NUMBER[(précision.

V_sal NUMBER (7. V_message VARCHAR2(80):= µTexte initial¶.Types PL/SQL et déclarations ‡ Déclarations de variables Identificateur Type [(précision. ‡ Suivre les conventions suivantes : Identifiant Variables Exception Variables Hôtes Curseurs Paramètre Préfix V_ E_ H_ C_ P_ Exemple V_sal E_RupStock H_Ename C_EMPDEPT10 P_EMPNO 10 . scale)] [NOT NULL] [:=expression]. Married BOOLEAN:=FALSE. Next_Week DATE :=DATE+7. Où Identificateur : règles Oracles habituelles NOT NULL : initialisation obligatoire Exemples DECLARE «.3).

deptno%TYPE. loc INTO v_deptno.loc%TYPE.Types PL/SQL et déclarations ‡ L¶attribut %Type Déclaration de variable en se référant au type d¶une variable ou d¶une colonne Identificateur nomTable. v_loc FROM « WHERE « Question Est-ce qu¶une variable déclaré avec %TYPE en se référant à une colonne NOT NULL hérite cette contrainte? 11 . Avantage Garantit la compatibilité de type surtout si la variable déclaré sera cité dans INTO pour initialisation à partir d¶une colonne Exemple DECLARE « V_deptno1 dept. BEGIN SELECT deptno. V_deptno2 deptno%TYPE.colonne%Type. V_loc dept.

Les variables logiques reçoivent directement TRUE.5):=3. V_ename :=µKING¶.scale)]:=expression. FALSE ou bien le résultat d¶une expression logique : Bien_Payé := v_sal>1500. 12 . V_message := TO_CHAR(v_compteur). Trouve := TRUE. Exemple V_compteur :=V_compteur+1. NotTrouve :=NOT Trouve.Types PL/SQL et déclarations ‡ Déclaration de constantes Identificateur CONSTANT Type [(precision. Exemple Pie CONSTANT NUMBER(9.14159. Affectations et expressions Identificateur := expression.

UPPER. SYSDATE.« LENGTH. etc. count.. LOWER. max.LASTDAY DECODE.) 13 .NEXTDAY..Types PL/SQL et déclarations ‡ Fonction SQL valides en PL/SQL La plupart des fonctions SQL sont utilisables dans les expressions PL/SQL : F° F° F° F° numériques mono-ligne : caractères mono-ligne : Date : d¶usage divers : ROUND. NVL. avg. Fonctions SQL NON valides dans les instructions procédurales : GREATEST. LEAST Fonctions agrégat (min.

14 . END. C NUMBER . on peut citer : ± Une meilleure lisibilité des programmes décomposés en sous-blocs ± Un meilleur usage des techniques de gestion et de propagation des exceptions DECLARE A CHAR . BEGIN «« DECLARE A INTEGER . « EXCEPTION WHEN «« THEN «. BEGIN « EXCEPTION « END .Types PL/SQL et déclarations ‡ Blocs Imbriqués et Portée d¶une variable Parmi les avantages de l¶imbrication. WHEN «« THEN «. B NUMBER .

BEGIN « IF Birthdate = bloc1.Birthdate THEN « « END IF. END bloc1. 15 . BEGIN «« DECLARE Birthdate DATE.Types PL/SQL et déclarations ‡ Blocs Imbriqués et Portée d¶une variable <<bloc1>> DECLARE Birthdate DATE . END .

Plan Chapitre 2 : Interaction avec Oracle et curseurs explicites ‡ ‡ ‡ ‡ ‡ Introduction Notion de curseur Curseurs implicites Curseurs explicites Conclusion 16 .

Report.Introduction ‡ Interaction avec Oracle : accéder et manipuler le contenu de la base de données. ‡ Les commandes SQL (SELECT ou du LMD) utilisées dans un bloc PL/SQL sont dites des curseurs. 17 . etc. ‡ Cette interaction se fait par les commandes SQL utilisées de deux façons : ± Autonome : à partir de l¶environnement SQL*Plus ± Bloc PL/SQL : environnement de développement comme Oracle Forms.

18 . UPDATE.Introduction DECLARE BEGIN SELECT INSERT. DELETE Instructions Procédurales EXCEPTION END .

Notion de Curseur ‡ A l¶exécution d¶une commande SQL. Zone Mémoire dans laquelle l¶ordre SELECT est compilé et exécuté Current Row On distingue deux types de curseurs : ‡ Les curseurs explicites ‡ Les curseurs implicites 19 . ‡ Cette zone est appelée curseur. Oracle Server ouvre une zone de mémoire dans laquelle la commande est analysée (parsed) et exécutée.

20 . lecture et traitement des lignes. La gestion d¶un curseur consiste à exécuter les opérations : ouverture du curseur. fermeture. Un curseur explicite doit être explicitement : ‡ ‡ Déclaré dans la section DECLARE Géré par le développeur dans la section exécutable.Notion de curseur ‡ Les curseurs explicites ± ± C¶est une commande SELECT pouvant ramener plusieurs lignes et qui est totalement à la charge du développeur.

Notion de curseur
‡ Les curseurs implicites
± Un curseur implicite est toute commande SQL (Select, Insert, Update, Delete) située dans la partie exécutable d¶un bloc :
‡ ‡ ‡ NON déclaré explicitement Nommé µSQL¶ implicitement par Oracle : tester l¶état du curseur Gestion automatique par PL/SQL : ouverture, traitement, fermeture.

±

Lorsque le curseur implicite est un ordre SELECT, alors il doit ramener une seule ligne, sinon erreur.

21

Les curseurs implicites
‡ Le tableau suivant indique, par opération de manipulation, les commandes SQL susceptibles de jouer le rôle de curseur implicite et/ou explicite :
Opération MAJ Curseur implicite Insert, Update, Delete Select Into Curseur explicite Aucune*

Interrogation

Select**

* Il n¶existe pas de curseur explicite de mise à jour ** Un curseur explicite ne peut être qu¶un select

22

Les curseurs implicites
‡ Exemple
DECLARE V_deptno NUMBER(2); V_Loc VARCHAR2(15); ..... BEGIN SELECT deptno, loc INTO v_deptno, v_loc Obligatoire FROM dept WHERE upper(dname) = µSALES¶; « END; Si le SELECT ne ramène pas exactement une ligne, PL/SQL réagit contre ces erreurs en levant (raise) des exceptions qu¶on peut piéger (trap) et gérer dans la section EXCEPTION.

23

Les curseurs implicites ‡ Exceptions du SELECT Condition Le SELECT identifie plus d une ligne Erreur Oracle Server ORA-01422 Le SELECT n identifie aucune ligne Erreur Oracle Server ORA-01403 Nom Exception TOO_MANY_ROWS NO_DATA_FOUND 24 .

Ces attributs sont utilisables comme des fonctions dans les ordres PL/SQL MAIS PAS dans les commandes SQL.Les curseurs implicites ‡ Attributs du curseur implicite PL/SQL fournit des attributs permettant d¶évaluer le résultat d¶un curseur implicite : Attribut SQL%ROWCOUNT SQL%FOUND SQL%NOTFOUND SQL%ISOPEN Description Entier : Nombre de lignes affectées par le dernier ordre SQL Booléen : TRUE si le dernier ordre SQL affecte au moins une ligne Booléen : TRUE si le dernier ordre SQL n affecte aucune ligne Toujours FALSE pour les curseurs implicites. 25 .

1 WHERE deptno = 10. BEGIN UPDATE EMP SET sal = sal*1. -. 26 .Les curseurs implicites ‡ Exemple DECLARE V_Rows_Updated NUMBER. V_Rows_Updated. V_Rows_Updated := SQL%ROWCOUNT. SYSDATE). END .SQL%ISOPEN est FALSE INSERT INTO History_Tab Values (µDept 10¶.

27 . !!Toutes les lignes seront MAJ (V_empno) END . EMP sal = 9000 empno = empno.Les curseurs implicites ‡ Les variables PL/SQL qui risquent d¶être utilisées dans des ordres SQL doivent être différentes des noms de colonnes des tables manipulées : DECLARE empno BEGIN UPDATE SET WHERE NUMBER(4) := 7788.

‡ Exigences du curseur explicite ± ± ± ± Déclaration Ouverture Accès aux lignes du curseur Fermeture Section DECLARE Section EXECUTABLE 28 .Les curseurs explicites ‡ Motivation ± Besoin de consulter n-uplets issus d¶une ou de plusieurs tables de la base de données ± Effectuer des traitements en examinant chaque ligne individuellement ‡ Curseur explicite ± Est une commande Select déclaré et nommé ± Généralisation du curseur implicite d¶interrogation ± Possédant les quatre attributs suivants : %ISOPEN %FOUND ISOPEN. FOUND. %NOTFOUND et %ROWCOUNT ROWCOUNT.

order by Paramètre : est un paramètre formel décrit comme suit : Nom_paramètre [IN] Type [{:=|DEFAULT} valeur] FOR UPDATE [OF colonne1. having.«] [NOWAIT]]. paramètre2.«)] IS Commande_SELECT [FOR UPDATE [OF colonne1.Les curseurs explicites ‡ Déclaration d¶un curseur : Syntaxe CURSOR nom_curseur [(paramètre1.«] : place un verrou exclusif portant sur des n-uplets de la table du SELECT [OF colonne1.«] : les colonnes à mettre à jour par le curseur sont verrouillées NOWAIT : pas d¶attente pour accéder aux n-uplets 29 . colonne2. Où nom_curseur : est le nom du curseur Commande_SELECT : est une requête pouvant utiliser les clauses habituelles (group by. colonne2. . colonne2.

30 . ************************************************************** CURSOR C2_Cher (P_Labno IN NUMBER) IS -. P_Max NUMBER DEFAULT 99) IS SELECT «.IN est optionnel SELECT Grade. ************************************************************** CURSOR C3_CHER (P_Min NUMBER DEFAULT 0. FROM «. WHERE BETWEEN P_Min AND P_Max.Les curseurs explicites ‡ Déclaration d¶un curseur : Exemples DECLARE «« CURSOR C1_Cher IS ± curseur non paramétré SELECT Cnom. Cnom FROM chercheur WHERE Labno = P_Labno. Labno FROM chercheur WHERE Sal> 1200.

OPEN C3_Cher.Les curseurs explicites ‡ Ouverture d¶un curseur : Syntaxe OPEN nom_curseur [(paramètre_effectif. OPEN C2_Cher (10).«)].|V_Labno :=10. OPEN C2_Cher (V_Labno).| SELECT Grade. OPEN C2_Cher (10). ‡ Exemples OPEN C1_Cher. Cnom FROM chercheur WHERE Labno = 10. Current ROW ZONE Mémoire où l¶ordre SELECT est compilé et exécuté Manager CLARK President kING Clerk Miller Active Set of Rows 31 .

variable2.«.Les curseurs explicites ‡ Accès aux lignes d¶un curseur : Syntaxe FETCH nom_curseur INTO variable1. ‡ Fonctionnalités ± Ramène le contenu de la ligne courante ± Assigne les données dans les variables de INTO ± Déplace le pointeur vers la ligne suivante 32 .

EXIT WHEN C1_Cher%NOTFOUND. V_Labno Chercheur. V_Cnom Chercheur. V_Labno. BEGIN OPEN C1_Cher.Les curseurs explicites ‡ Accès aux lignes d¶un curseur : Exemple DECLARE CURSOR C1_Cher IS SELECT Cnom. Labno FROM Chercheur WHERE Sal >1400. END --fin du bloc 33 .--Exécution du SELECT LOOP FETCH C1_Cher INTO V_Cnom. « END.Labtno%TYPE.Cnom%TYPE.--Test de sortie -ici %FOUND est TRUE -traitement de la ligne ramenée par FETCH « END LOOP.

sinon il prend la valeur FALSE ± %ROWCOUNT Cet attribut retourne le nombre de lignes impactées par la dernière instruction SQL 34 . ‡ Remarque toute opération sur un curseur fermé (Fetch. %attribut) engendra l¶exception prédéfinie INVALID_CURSOR ‡ Attributs d¶un curseur explicite ± %FOUND Cet attribut prend la valeur TRUE lorsque une ligne est ramenée.Les curseurs explicites ‡ Fermeture d¶un curseur ± Libération de l¶espace mémoire alloué ± Réouverture si nécessaire ‡ Syntaxe CLOSE nom_curseur. sinon il prend la valeur TRUE ± %ISOPEN Cet attribut prend la valeur TRUE lorsque le curseur indiqué est ouvert. sinon il prend la valeur FALSE ± %NOTFOUND Cet attribut prend la valeur FALSE lorsque une ligne est ramenée.

END.Cnom.Rec1 de même schéma que C1 V_Cnom Chercheur. « BEGIN OPEN C1. V_Cnom:=Rec1.__ fin bloc END 35 . ‡ Exemple DECLARE CURSOR C1 IS SELECT Cnom.-. V_Salaire := Rec1.Les curseurs explicites ‡ Curseur et enregistrement : Syntaxe Nom_enregistrement nom_curseur%ROWTYPE. Sal+NVL(prime.Cnom%TYPE. Close C1. LOOP FETCH C1 INTO Rec1 Rec1.0) salaire FROM chercheur WHERE Labno=10.salaire. Rec1 C1%ROWTYPE C1%ROWTYPE. EXIT WHEN C1%NOTFOUND OR C1%ROWCOUNT >5. END LOOP.

Labno=10 Then UPDATE Chercheur SET Labno =99²supposé existant WHERE CURRENT OF C1 C1. CLOSE C1.suite de traitement END LOOP LOOP.Les curseurs explicites ‡ Clauses WHERE CURRENT OF et FOR UPDATE Les commandes SQL (UPDATE et DELETE) peuvent utiliser la clause WHERE CURRENT OF nom_curseur» pour référencer la ligne courante d¶un curseur explicite ‡ Exemple DECLARE CURSOR C1 IS SELECT Cnom. Labno FROM Chercheur WHERE Sal>1400 FOR UPDATE of Labno. LOOP FETCH C1 INTO Ligne_C1. Commit. IF Ligne_C1. BEGIN OPEN C1. END. Ligne_C1 C1%ROWTYPE. END --fin bloc 36 . EXIT WHEN C1%NOTFOUND. END IF -.

Les curseurs explicites
‡ Boucle dédiée curseur
PL/SQL offre une boucle FOR spéciale pour les curseurs explicites. Elle prend en charge toutes les opérations du curseur (OPEN, FETCH, EXIT et CLOSE) ‡ Syntaxe 1 : cas d¶un curseur nommé
FOR nom_record IN nom_curseur [(paramètre,«)] LOOP « --traitement de la ligne courante END LOOP;

‡ Syntaxe 2 : cas d¶un curseur anonyme
FOR nom_record IN (Commande_SELECT) LOOP « --traitement de la ligne courante END LOOP;
37

Les curseurs explicites
‡ Boucle dédiée curseur : Exemple 1
DECLARE CURSOR C1 (P_DATEREC DATE) IS SELECT Cnom, Grade FROM Chercheur WHERE DATEREC < P_DATEREC; BEGIN FOR REC IN C1 (¶01-JAN-99¶) -- curseur ouvert LOOP -- ici une ligne est disponible -- traitement des lignes, une par itération END LOOP; /* Ici le curseur est automatiquement fermé les attributs ne sont pas utilisables Toute référence à REC est invalide*/ -- suite traitement END;

38

Les curseurs explicites
‡ Boucle dédiée curseur : Exemple 2
DECLARE «« BEGIN « V_TOT_SAL NUMBER :=0; FOR REC IN (SELECT Cnom, Sal FROM Chercheur WHERE Labno=10) LOOP -- traitement de la ligne courante IF Rec.Sal > 1000 THEN « END LOOP; «. END;
39

SQL%ISOPEN ‡ Curseurs explicites ± ± ± ± ± Déclaration de curseur CURSOR Ouverture de curseur OPEN Accès aux lignes d¶un curseur FETCH Fermeture de curseur CLOSE Attributs d¶un curseur explicite :%ROWCOUNT. %ISOPEN ± Curseur et enregistrement : Nom_enregistrement nom_curseur%ROWTYPE ± Clauses WHERE CURRENT OF et FOR UPDATE ± Boucle dédiée curseur : gestion automatique de toutes les opérations d¶un curseur (OPEN.Conclusion ‡ Notion de curseur : une zone de mémoire dans laquelle la commande est analysée (parsed) et exécutée ‡ Curseurs implicites ± Curseur implicite : SELECT «INTO ± Autres curseurs implicites : INSRET. SQL%NOTFOUND. UPDATE et DELETE après BEGIN ± Attributs des curseurs implicites :SQL%ROWCOUNT. SQL%FOUND. %FOUND. %NOTFOUND. EXIT et CLOSE) 40 . FETCH.

3. Introduction Gestion des exceptions Propagation des exceptions Envoie de message d¶erreur avec RAISE_APPLICATION_ERROR 5. 4. 2.Plan Chapitre 3 : Gestion des exceptions 1. Traitement des exceptions dans les autres environnements 41 .

Introduction ‡ Lors de l¶exécution d¶un bloc PL/SQL. Les conditions de ces erreurs sont appelés des exceptions ‡ Oracle distingue deux types d¶exception : ± Les exceptions internes ± Les exceptions utilisateur (User-Exceptions) 42 . certaines erreurs peuvent se produire.

Introduction ‡ Les exceptions internes ± Détecter implicitement par le serveur Oracle ± Elles sont libellées et codées (ORA-XXXXX) ± Deux types d¶exception internes : ‡ Nommées (ou Prédéfinies) ‡ Anonymes (ou Non prédéfinies) 43 .

provoque l¶échec du bloc PL/SQL ‡ Pour se protéger contre ces situations. L¶endroit de ce traitement est la section EXCEPTION 44 . interne ou utilisateur. La gestion d¶une exception consiste à prévoir un traitement approprié qui absorbe ou résout l¶erreur. il est possible de gérer ces exceptions.Introduction ‡ Les exceptions utilisateur ± Détecter explicitement par le développeur ± Elles sont définies dans la section DECLARE ‡ Une exception non traitée.

45 .Gestion des exceptions ‡ En cas d¶une exception rencontrée dans la section exécutable d¶un bloc le contrôle passe immédiatement à la section EXCEPTION du même bloc pour chercher si un gestionnaire approprié existe DECLARE BEGIN Erreur Recherche d¶un gestionnaire approprié EXECPTION END.

Gestion des exceptions ‡ Comment gérer une exception? Gérer une exception c¶est prévoir un traitement correspondant à l¶erreur rencontrée ‡ Pourquoi gérer une exception? Transformer un échec en succès Eviter la propagation de l¶exception vers les blocs parents ‡ Où gérer une exception? Tout bloc PL/SQL prévoit une section optionnelle de gestion des exceptions 46 .

-.corps du bloc EXCEPTION WHEN Nom_Exception THEN Instructions. -.Gestion des exceptions ‡ Syntaxe -.] END.gestionnaire d¶exception WHEN [WHEN OTHERS THEN «.fin du bloc Nom_Exception : interne ou utilisateur 47 .

PUT_LINE (µNom Chercheur¶||V_Cnom).PUT_LINE (µPlusieurs chercheurs Trouvés.Gestion des exceptions ‡ Exemple DECLARE V_Cnom Chercheur. END 48 . DBMS_OUTPUT.¶). --Utiliser un curseur explicite END. Exception WHEN TOO_MANY_ROWS THEN DBMS_OUTPUT.Cnom%TYPE. BEGIN SELECT Cnom INTO V_Cnom FROM Chercheur WHERE Labno =10.

Gestion des exceptions ‡ Exceptions prédéfinies (internes) ± Elles sont prédéfinies par Oracle ± Elles possèdent des noms significatifs ± Elles sont automatiquement provoquées ± Les exceptions les plus courantes sont les suivantes : ‡ Exception DUP_VAL_ON_INDEX (ORA-00001) ‡ Exception NO_DATA_FOUND (ORA-01403) ‡ Exception TOO_MANY_ROWS (ORA-01422) ‡ Exception VALUE_ERROR (ORA-06502) ‡ Exception INVALID_NUMBER (ORA-01722) ‡ Exception ZERO_DIVIDE (ORA-01476) ‡ Exception INVALID_CURSOR (ORA-01722) 49 .

Gestion des exceptions ‡ Exception DUP_VAL_ON_INDEX (ORA-00001) ± Condition de provocation : lorsqu¶une commande SQL tente d¶insérer une valeur dupliquée dans une colonne définie avec un index unique (UNIQUE INDEX ou PRIMARY KEY) ± Exemple : cas d¶insertion avec duplication de clé primaire BEGIN INSERT INTO Etudiant (NumETUD. EXCEPTION WHEN DUP_VAL_ON_INDEX THEN DBMS_OUTPUT. FilETUD) VALUES (10. µInformatique¶).PUT_LINE déjà.¶). µDupont¶. END. NomETUD. 50 (µInsertion rejetée :NumETUD existe .

implicite ± Remarque : L¶absence d¶un gestionnaire pour l¶exception NO_DATA_FOUND entraîne une sortie du bloc avec échec 51 .NumETUD%TYPE :=10. « END. EXECPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE (µEtudiant 10 Inexistant¶).Gestion des exceptions ‡ Exception NO_DATA_FOUND (ORA-01403) ± Condition de provocation : lorsqu¶un curseur d¶interrogation ne retourne aucune ligne ± Exemple : cas de recherche d¶un étudiant inexistant DECLARE ETUDIANT_REC ETUDIANT%ROWTYPE. V_NumETUD ETUDIANT. BEGIN SELECT * INTO ETUDIANT_REC FROM ETUDIANT WHERE NumETUD= V_NumETUD.

PUT_LINE (µPlusieurs étudiants trouvés. EXECPTION WHEN TOO_MANY_ROWS THEN DBMS_OUTPUT. 52 .NomETUD%TYPE. BEGIN SELECT NomETUD INTO V_NomETUD FROM ETUDIANT WHERE FilETUD= µInformatique¶.¶).Gestion des exceptions ‡ Exception TOO_MANY_ROWS (ORA-01422) ± Condition de provocation : lorsqu¶un curseur implicite d¶interrogation identifie plus qu¶un seul n-uplet à retourner ± Exemple : plusieurs étudiants ayant la même filière DECLARE V_NomETUD ETUDIANT. « END.

EXCEPTION WHEN VALUE_ERROR THEN DBMS_OUTPUT.Gestion des exceptions ‡ Exception VALUE_ERROR (ORA-06502) ± Condition de provocation : de conversion DECLARE V_message VARCHAR2 (10). en cas de troncature ou d¶erreur ± Exemple : Affectation générant une troncature 53 . BEGIN V_message :=µChaîne trop longue¶. END.PUT_LINE (µErreur de troncature¶).

EXCEPTION WHEN INVALID_NUMBER THEN DBMS_OUTPUT.PUT_LINE (µException INVALID_NUMBER¶). 54 . END. BEGIN UPDATE EMP SET MGR = V_mgr WHERE empno=7902.Gestion des exceptions ‡ Exception INVALID_NUMBER (ORA-01722) ± Condition de provocation : lorsqu¶une commande SQL spécifie un nombre invalide ± Exemple DECLARE V_mgr VARCHAR2 (4).

3). V_nombre2 int :=5. BEGIN V_resultat := 100/(V_nombre1 -2* V_nombre2). EXCEPTION WHEN ZERO_DIVIDE THEN DBMS_OUTPUT. 55 . V_resultat number (5.PUT_LINE (µException ZERO_DIVIDE Exception ZERO_DIVIDE¶).Gestion des exceptions ‡ Exception ZERO_DIVIDE (ORA-01476) ± Condition de provocation : tentative de division par ZERO ± Exemple DECLARE V_nombre1 int :=10. END.

%ROWCOUNT) 56 .Gestion des exceptions ‡ Exception INVALID_CURSOR (ORA-01722) ± Condition de provocation : au moment ou un curseur fermé est référencé dans une opération de lecture (FETCH). de fermeture (CLOSE) ou via des attributs (%FOUND. %NOTFOUND.

Gestion des exceptions ‡ Exceptions génériques OTHERS ² Condition de provocation : toute exception non gérée ² WHEN OTHERS doit être la dernière ‡ Les fonctions SQLCODE et SQLERRM Quand une exception se produit. on peut récupérer son code et son message d¶erreur. Ceci est particulièrement intéressant pour les exceptions manipulées avec OTHERS SQLCODE : Renvoie un entier représentant le n° de l¶erreur (99999) qui a provoquée l¶exception et Zéro sinon (pas d¶erreur) SQLERRM : Renvoie un texte composé du numéro de l¶erreur et d¶un message complet associé à l¶exception rencontrée. de la forme (ORA-XXXX: texte explicatif) 57 .

± Déclenchement : syntaxe RAISE nom_exception. ± Capture : syntaxe WHEN nom_exception THEN instructions. 58 .Gestion des exceptions ‡ Exceptions de l¶utilisateur Toute exception utilisateur doit être déclarée et explicitement provoquée pour la capturer selon les étapes suivantes : ± Déclaration : syntaxe Nom_exception EXCEPTION.

V_Qtestksec FROM Stock WHERE Numart=1234.--déclaration EXCEPTION.Qtestk%TYPE.Qtestksec%TYPE. END. 59 . --suite IF V_Qtestk <V_Qtestsec THEN RAISE E_Rupt_Stk. BEGIN SELECT Qtestk.--déclaration V_Qtestk Art. --provocation --provocation END IF.PUT_LINE (µStock insuffisant.Gestion des exceptions! exceptions! ‡ Exceptions de l¶utilisateur ± Exemple DECLARE E_Rupt_Stk EXCEPTION. V_Qtestksec Art. Qtestksec INTO V_Qtestk. --suite EXCEPTION WHEN E_Rupt_Stk THEN --gestionnaire --gestionnaire DBMS_OUTPUT.article 1234¶).

60 . Prévoir un gestionnaire d¶exception 1. Associer l¶exception déclarée à un numéro d¶erreur interne PRAGMA EXCEPTION_INIT (nom_exception. no_err_interne) . Les erreurs internes pour lesquelles le développeur assigne un nom sont dites des exceptions Non Prédéfinies ‡ Etapes de capture d¶une Exception Non Prédéfinie 1. ‡ Remarque : les exceptions internes : ± ± sont provoquées implicitement peuvent être provoquées explicitement (RAISE nom_except). PL/SQL offre une souplesse additionnelle au développeur en permettant de nommer des erreurs internes ce qui permettra de les distinguer individuellement et de les utiliser comme les exceptions prédéfinies. Idem . 2. 3.Gestion des exceptions ‡ Exceptions internes non prédéfinies Les exceptions internes non prédéfinies peuvent être piégées par la clause générique WHEN OTHERS. Déclarer l¶exception Nom_exception EXCEPTION .

. /*Oracle return error number -1031 if.Gestionnaire d¶exception END. you try to UPDATE a table for which you have only SELECT privileges */ BEGIN . PRAGMA EXCEPTION_INIT(Privilege_Insuffisant. for example. -1031). « EXCEPTION WHEN Privilege_Insuffisant THEN -.Gestion des exceptions ‡ Exemple DECLARE Privilege_Insuffisant EXCEPTION.. 61 .

Lorsqu¶une exception n¶est pas gérée dans son bloc. elle se transmet au bloc parent : cette transmission de l¶erreur entre blocs est appelée propagation.Propagation des exceptions ‡ Principe Lorsqu¶un sous-bloc traite une exception. 62 . il se termine normalement (succès) et le contrôle reprend dans le bloc parent immédiatement après l¶instruction END du sous-bloc.

Propagation des exceptions ‡ Exceptions de la section exécutable BEGIN «« -. Exception -. 63 .Exception X déclenché ici EXCEPTION ± Aucun gestionnaire pour l¶exception X Propagation END.il y a un gestionnaire pour l¶exception x END.

Propagation des exceptions ‡ Avantages de la propagation ± Gérer les exceptions spécifiques à certaines instructions au niveau de leur bloc pour assurer la sûreté de fonctionnement de ces blocs ± Ceci permettra également cascade de l¶erreur d¶éviter une reproduction en 64 .

Affectation illégale. 65 . provoque l¶exception VALUE_ERROR Ne peut être exécutée pour l¶exception VALUE_ERROR Bloc en échec Exception VALUE_ERROR reconduite DECLARE V_NO NUMBER (3):=µABC¶ BEGIN «.Propagation des exceptions ‡ Exceptions de la section DECLARE Toute exception provoquée par l¶initialisation d¶une variable lors de sa déclaration se propage et ne peut être traitée dans son bloc même si un gestionnaire d¶exception approprié (ou OTHERS) y est prévu. EXCEPTION WHEN OTHERS THEN « END.

l¶exception se propage et ne peut être capturée dans le même bloc : le principe est d¶activer un seul gestionnaire d¶exception à la fois dans un bloc ‡ Exemple EXCEPTION WHEN INVALID_NUMBER THEN INSERT INTO «--peut causer DUP_VAL_ON_INDEX WHEN DUP_VAL_ON_INDEX THEN « END.Propagation des exceptions ‡ Exceptions de la section EXCEPTION Un gestionnaire d¶exception peut provoquer une autre exception implicitement (interne) ou explicitement (RAISE). 66 . auxquels cas.

La commande RAISE permet cette reproduction de l¶erreur EXCEPTION WHEN E_STOCK_INSUFFISANT THEN -...Propagation des exceptions ‡ Gestion locale et reproduction d¶une exception Parfois... on a besoin de traiter localement une exception provoquée puis de la transmettre au bloc parent. --Reproduit l¶exception courante .. -. END.. 67 .fin sous bloc EXCEPTION WHEN E_STOCK_INSUFFISANT THEN -.Gérer l¶erreur différemment . END .Gérer localement l¶erreur RAISE.

«. no-erreur : doit être compris entre -20000 et -20999 message-erreur : texte de 512 caractères maximum DECLARE E_mon-Exception EXCEPTION . L¶exécution de RAISE_APPLICATION_ERROR reproduit l¶erreur et annule la transaction en cours. BEGIN «. Raise E_mon-Exception. . 68 END .Envoie de message d¶erreur avec RAISE_APPLICATION_ERROR ‡ RAISE_APPLICATION_ERROR est une procédure du package DBMS_STANDARD. Elle est utilisable dans les sections BEGIN et EXCEPTION. s/p PL/SQL. message_erreur). ‡ Syntaxe RAISE_APPLICATION_ERROR (no_erreur. utile pour produire des messages d¶erreur applicatifs spécifiques à l¶environnement appelant (SQL*Plus. application client). µmessage applicatif¶). EXCEPTION E_mon-Exception THEN WHEN RAISE_APPLICATION_ERROR(-20000.

Le libellé et le numéro des exceptions non traitées sont accessibles par un trigger au moyen des fonctions ERROR_CODE et ERROR_TEXT.Traitement des exceptions dans les autres environnements ‡ Il est possible de propager une exception vers l¶environnement appelant au lieu de la traiter dans le bloc PL/SQL courant ‡ Chaque environnement possède sa propre façon de traiter les erreurs. 69 Précompilateur C . Le numéro des exceptions non traitées est accessibles via la structure SQLCA. Environnement appelant Possibilité de Exceptions SQL* Plus ou Procedure Builder Developer/2000 Forms traitement des Le libellé et le numéro des exceptions non traitées sont affichés à l écran.

Les sous programmes 2. les sous programmes stockés et les packages 1.Plan Chapitre 4 : Les sous programmes. Les sous programmes stockés 3. Les packages 70 .

Appels Mutuels entre sous programmes 71 . Correspondance entre paramètres Actuels et Formels 3. Introduction 2. Exceptions dans les sous programmes et impact sur les paramètres 5. Procédures 1.Plan Section 1 : Les sous programmes 1. Fonctions 4. Modes de passage des paramètres 2.

cette pratique n¶est pas recommandée pour deux raisons majeures : ± Réduit la lisibilité du code et rend plus difficile sa maintenance ± Les blocs emboîtés ne peuvent pas être appelés ‡ Les sous programmes ± PL/SQL offre programmes la possibilité de travailler avec des sous ± Un sous programme PL/SQL est un bloc nommé défini dans la section DECLARE et pouvant posséder des paramètres ± Il est réutilisable et facilite la maintenance des applications 72 .Introduction ‡ Bien que PL/SQL permet l¶imbrication de blocs.

73 .Procédures ‡ Syntaxe PROCEDURE nom_procédure [(paramètre [. paramètre«])] {IS |AS} /*déclarations si nécessaires*/ BEGIN --instructions exécutables [EXCEPTION --Section optionnelle de --Gestion des exceptions ] END [nom_procédure].

USER. User_Trace_Date) VALUES (UID. PROCEDURE RECORD_Trace As BEGIN INSERT INTO Tab_Trace(User_Uid.Procédures ‡ Exemple 1 (procédure sans paramètres) Enregistrer l¶utilisateur courant et la date système dans la table Tab_Trace (User_Uid. 1. EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE (SUBSTR (SQLERRM. END RECORD_Trace. User_Trace_Date) DECLARE «. SYSDATE).80).--appel procédure END.--fin bloc externe 74 . User_Name. -.autres déclarations BEGIN ±début bloc externe RECORD_Trace. User_Name.

PUT_LINE (µMAJ Réussie¶). END.EMPNO%TYPE. -. PROCEDURE AUGMENTE_SAL (P_EMPNO EMP. END IF END AUGMENTE_SAL.--fin bloc externe 75 . ELSE DBMS_OUTPUT.autres déclarations BEGIN ±début bloc externe AUGMENTE_SAL (1234.Procédures ‡ Exemple 2 (procédure avec paramètres) Augmenter le salaire d¶un employé identifié par EMPNO d¶un montant donné DECLARE «.PUT_LINE (µMAJ Non Effectuée¶). P_Montant NUMBER) IS BEGIN UPDATE EMP SET SAL =SAL+P_Montant WHERE EMPNO=P_EMPNO AND P_EMPNO NOT NULL.1000). IF SQL%NOTFOUND THEN DBMS_OUTPUT.

Modes de passage des paramètres ‡ Nom_param [IN|OUT|IN OUT ] Type [{:=|DEFAULT} expr] Paramètre d¶appel (1) Le sous PG reçoit une copie (2) Le sous PG fournit un résultat (1)&(2) Paramètre formel IN (read-only) OUT (write-only) IN OUT (read-write) IN : Passage par valeur IN OUT : Passage par @ échange dans les deux sens OUT : Passage par @ pour retourner un résultat 76 .

--légale V_local :=P_Out. P_Out OUT NUMBER.Affectation illégale P_Out est null ici P_Out:=10. P_InOut NUMBER ) IS V_Local NUMBER. END ModeParam. -. BEGIN P_In :=20. 77 . --illégale (Write only) P_InOut reçoit la valeur du param d¶appel P_InOut :=P_InOut*3.Modes de passage des paramètres ‡ Exemple PROCEDURE ModeParam (P_In IN NUMBER.

Modes de passage des paramètres ‡ Teste de la procédure ModeParam DECLARE V_IN NUMBER := 1.PUT_LINE (µV_INOUT : µ || V_INOUT). V_OUT. BEGIN ModeParam (V_IN. DBMS_OUTPUT. V_INOUT NUMBER :=3. END. V_INOUT). DBMS_OUTPUT. ‡ Test du bloc V_IN : 1 V_OUT : 10 V_INOUT : 9 Procédure PL/SQL terminée avec succès 78 . V_OUT NUMBER :=2. DBMS_OUTPUT.PUT_LINE (µV_OUT : µ || V_OUT).PUT_LINE (µV_IN : µ || V_IN).

ou un traitement quelconque END CorrespondanceParam.Correspondance entre paramètres Actuels et Formels ‡ Correspondance par position ± Fournir des paramètres d¶appel dans le même ordre que celui des paramètres de définition du sous PG ± Les paramètres avec DEFAULT doivent être les derniers pour pouvoir ne pas leur fournir de valeurs ‡ Correspondance par nom ± Permet de ne pas respecter l¶ordre de définition ± Utile pour des sous PG avec un nombre important de paramètres PROCEDURE CorrespondanceParam (P_A NUMBER. V_B. P_B=>V_B. V_C. 79 .-. P_C BOOLEAN. P_D DATE) as BEGIN NULL. VARCHAR2. P_B Par position : CorrespondanceParam (V_A. P_D=>V_D) (P_A=>V_A. V_D). Par nom : CorrespondanceParam P_C=>V_C.

EXCEPTION [EXCEPTION --Gestionnaires d¶exceptions] END [nom_fonction] . paramètre«])] RETURN type IS /*déclarations si nécessaires*/ BEGIN --instructions exécutables --RETURN expression. ‡ Le type de la fonction peut utiliser %TYPE ‡ Mêmes modes de passage de paramètres que les procédures 80 .Fonctions Une fonction est un sous programme qui retourne une valeur explicitement par la clause RETURN ‡ SYNTAXE FUNCTION nom_fonction [(paramètre [.

Fonctions ‡ Exemple La fonction Avg_Sal retourne le salaire moyen des chercheurs d¶un laboratoire DECLARE --déclarations si nécessaires V_Sal_Moy NUMBER (10. 80)).Appel fonction DBMS_OUTPUT.Labno%TYPE) RETURN NUMBER IS V_Avg_Sal Chercheur. EXCEPTION WHEN OTHERS THEN RAISE_APPLICATION_ERROR (-20110.PUT_LINE (µSalaire Moyen :¶|| V_Sal_Moy).3). FUNCTION Avg_Sal (P_Labno IN Chercheur.--fin bloc externe 81 . SUBSTR(SQLERRM.-. BEGIN SELECT AVG(Sal) INTO V_Avg_Sal FROM Chercheur WHERE Labno=P_Labno. 1. RETURN V_Avg_Sal. END AVG_SAL. END. --autres déclarations BEGIN V_Sal_Moy := Avg_Sal (10).Sal%TYPE.

Exceptions dans les sous-programmes souset Impact sur les paramètres
‡ Dans un sous programme, une exception non traitée se reproduit selon le principe de propagation. En conséquence, les valeurs des paramètres formels ne seront pas récupérées dans les paramètres actuels

82

Exceptions dans les sous-programmes souset Impact sur les paramètres
‡ Exemple
DECLARE PROCEDURE Proc_RaiseError (p_Raise IN BOOLEAN , p_Parameter OUT NUMBER) AS My_Exception Exception; BEGIN p_Parameter := 10; IF p_Raise THEN RAISE My_Exception; END IF; END Proc_RaiseError; v_Temp NUMBER := 5; BEGIN DBMS_OUTPUT.PUT_LINE('V_temp avant Premier appel : '||v_temp); Proc_RaiseError(FALSE, v_Temp); DBMS_OUTPUT.PUT_LINE('V_temp Après appel en succès:'||v_temp); v_Temp := 8; DBMS_OUTPUT.PUT_LINE('V_temp Avant second appel : '||v_temp); Proc_RaiseError(TRUE, v_Temp); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('V_temp après second appel:'||v_temp); END;

V_temp avant Premier appel : 5 V_temp Après appel en succès : 10 V_temp Avant second appel : 8 V_temp après second appel : 8

83

Appels mutuels entre soussousprogrammes
‡ Puisque les noms des sous programmes locaux sont des identificateurs, ils doivent être déclarés avant qu¶ils soient utilisés. Par exemple, si un sous programme A appelle un sous programme B, B doit être déclaré avant A.

‡ Dans le cas de références mutuelles (A appelle B et B appelle A), il faut procéder à une déclaration en avant (forward) de l¶un ou même des deux sous programmes selon l¶utilisation

84

END IF. END B. END A. A(p_Counter). PROCEDURE B(p_Counter IN OUT BINARY_INTEGER) IS BEGIN p_Counter := p_Counter . 85 .Forward declaration of procedure B.1. END. -.Appels mutuels entre soussousprogrammes ‡ Exemple DECLARE v_TempVal BINARY_INTEGER := 5. p_Counter := p_Counter .1. PROCEDURE A(p_Counter IN OUT BINARY_INTEGER) IS BEGIN IF p_Counter > 0 THEN B(p_Counter). PROCEDURE B(p_Counter IN OUT BINARY_INTEGER). BEGIN B(v_TempVal).

Si le salaire de l¶employé est NULL. la commission vaut 0. Ecrire un bloc PL/SQL qui appelle une procédure permettant de calculer le montant de la commission d¶un employé donné. Ecrire un bloc PL/SQL qui appelle une fonction permettant de sélectionner le plus grand numéro de département (DEPTNO) de la table DEPT et le stocke dans une variable SQL*Plus.Exercices 1. la commission vaut 15% du salaire. Si le salaire de l¶employé est supérieur à 15OO$. 86 . en fonction de son salaire. Affichez le résultat à l¶écran. la commission vaut 10% du salaire. Si le salaire de l¶employé est compris entre 1OOO$ et 1500$. 2. Si le salaire de l¶employé est inférieur à 1OOO$. la commission vaut 20% du salaire.

EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT. END Max_Dept. Return V_deptno. BEGIN SELECT MAX (deptno) INTO V_deptno FROM dept.Exercices DECLARE V_deptno_Max Number. FUNCTION Max_Dept RETURN Number IS V_deptno NUMBER . END .PUT_LINE (V_deptno_Max). DBMS_OUTPUT. BEGIN V_deptno_Max := Max_Dept . 87 .PUT_LINE (µaucun département enregistré¶).

UPDATE emp SET comm= V_comm.DECLARE Exercices PROCEDURE Calcul_Commission (P_empno emp.20. BEGIN Calcul_Commission (10).10. IF V_sal <1000 then V_comm:=V_sal*0. 88 . --peut être une variable globale BEGIN SELECT sal INTO V_sal FROM emp Where empno= P_empno. END IF. V_comm emp.15. ELSIF V_sal > 1500 then V_comm:=V_sal*0. ELSIF V_sal Between 1000 and 1500 then V_comm:=V_sal*0.comm%TYPE. END Calcul_Commission.sal%TYPE. Else V_comm:=0.empno%TYPE) IS V_sal emp.--appel de la procédure END.

5. 4. 7.Plan ‡ 1. Section 2 : Les sous-programmes stockés Introduction Procédures stockées Fonctions stockées Suppression de sous programmes stockés Dictionnaire de données et sous-programmes stockés Sous-programmes stockés versus sous programmes locaux Sous-programmes et privilèges 89 . 2. 6. 3.

C¶est-à-dire qu¶elle n¶existe plus lorsque l¶exécution du bloc anonyme est terminée ‡ Fonction ou Procédure stockée : sous programme (en tant qu¶objet du dictionnaire Oracle) appelable par un utilisateur. directement ou indirectement 90 . Cette dernière est temporaire.Introduction ‡ La différence entre une procédure stockée et une procédure déclarée et utilisée dans un bloc anonyme est importante.

. EXCEPTION WHEN NO_DATA_FOUND THEN «. SQL> EXECUTE raise_salary(7788. END IF.sal%type. E_sal_NULL EXCEPTION.instructions exécutables END raise_salary raise_salary. IF v_sal_actuel IS NULL THEN RAISE E_sal_NULL. p_montant Number) IS V_sal_actuel emp. BEGIN SELECT sal INTO v_sal_actuel FROM emp WHERE empno = p_empno and p_empno is not null.empno%TYPE.PROCEDURES Stockées ‡ Syntaxe CREATE [OR REPLACE] Procedure Où Procedure : syntaxe habituelle de déclaration d¶une procédure OR REPLACE : Remplace une procédure existante (suppression + re-création) ‡ Exemple CREATE OR REPLACE PROCEDURE raise_salary (p_empno emp. 1000). ELSE UPDATE emp SET sal = sal + p_montant WHERE empno = p_empno. 91 . WHEN E_sal_NULL THEN -.

sal%type. END. BEGIN SELECT AVG(SAL) INTO v_avg_sal FROM EMP WHERE deptno = p_deptno AND p_deptno is not null. DBMS_OUTPUT. BEGIN SELECT AVG(SAL) INTO v_avg_sal END. Salaire Moyen : 2073. salaire Moyen : 2916.PUT_LINE (concat (µsalaire Moyen : µ. DBMS_OUTPUT.21 CREATE OR REPLACE PROCEDURE Affiche_Sal_Moy_deptno (p_deptno dept.sal%type .67 FROM EMP .PROCEDURES Stockées ‡ IS V_avg_sal emp. SQL> EXECUTE Affiche_Sal_Moy_deptno(10).deptno%type) IS V_avg_sal emp. Autres Exemples CREATE OR REPLACE PROCEDURE Affiche_Sal_Moy 92 .v_avg_sal).PUT_LINE(µsalaire Moyen : µ||v_avg_sal). SQL> EXECUTE affiche_sal_moy.

ename%type) IS BEGIN SELECT FROM WHERE EXCEPTION WHEN NO_DATA_FOUND Then DBMS_OUTPUT.PROCEDURES Stockées! Stockées! ‡ Autres Exemples CREATE OR REPLACE PROCEDURE get_emp_name (p_empno IN emp. µSCOTT¶ 93 ename emp INTO p_ename empno = p_empno and p_empno is not null. SQL> EXECUTE get_emp_name (7788). .empno%type.PUT_LINE (µEmployé non Trouvé). p_ename OUT emp. END get_emp_name.

PROCEDURES Stockées ‡ CREATE PROCEDURE/FUNCTION Compile et Stocke dans le Dictionnaire de Oracle ‡ La vue USER_ERRORS Affiche les erreurs de compilation SQL>SHOW ERRORS (commade SQL*Plus) ‡ La vue USER_OBJECTS Présente les objets-Oracle de chaque utilisateur Name Null? ------------------------------.-------OBJECT_NAME OBJECT_ID OBJECT_TYPE CREATED STATUS Type -----------------------VARCHAR2(128) NUMBER VARCHAR2(13) DATE VARCHAR2(7) 94 .

95 .-------NAME NOT NULL TYPE LINE NOT NULL TEXT de chaque utilisateur Type -----------------------VARCHAR2(30) VARCHAR2(12) NUMBER VARCHAR2(2000) Possibilité de récupérer le texte source d¶1 sous programme stockée : SELECT line. Text FROM USER_SOURCE WHERE UPPER(NAME) = µnom_sous_prog¶ AND UPPER(TYPE) = µFUNCTION¶ ORDER BY line .PROCEDURES Stockées ‡ La vue USER_SOURCE Présente le code source des sous programmes Name Null? ------------------------------.

ename%type) 4 is 5 begin 6 select ename 7 into p_ename 8 from emp 9 where empno = p_empno.put_line (µemployé non trouvé¶). 13 end get_emp_name.PROCEDURES Stockées LINE TEXT --------.------------------------------------------------1 procedure get_emp_ename ( 2 p_empno in emp. 3 p_ename OUT emp. 96 .empno%type. 10 exception 11 when no_data_found then 12 dbms_output.

-. µDay¶)).FONCTIONS Stockées Doit retourner une valeur. CREATE [OR REPLACE] fonction Où fonction : syntaxe habituelle de déclaration d¶une fonction ‡ Exemple 1 CREATE OR REPLACE FUNCTION LIB_JOUR (p_date DATE) RETURN VARCHAR2 IS BEGIN RETURN (TO_CHAR(p_date. END. EXCEPTION When Others Then RETURN (NULL).appel de la fonction 97 . X V_Lib_Jour := Lib_Jour(sysdate) .

END. CLOSE C_EMP. 98 . V_SAL EMP.FONCTIONS Stockées ‡ Exemple 2 CREATE OR REPLACE FUNCTION SECOND_SAL_DEPTNO (P_DEPTNO DEPT. EXIT WHEN C_EMP%NOTFOUND OR C_EMP%ROWCOUNT=2. END LOOP .DEPTNO%TYPE) IS SELECT SAL FROM EMP WHERE DEPTNO = P_DEPTNO and P_DEPTNO IS NOT NULL ORDER BY SAL.SAL%TYPE DEFAULT NULL. RETURN(V_SAL). BEGIN OPEN C_EMP(P_DEPTNO). LOOP FETCH C_EMP INTO V_SAL.DEPTNO%TYPE) RETURN NUMBER IS /* DECLARATIONS */ CURSOR C_EMP (P_DEPTNO DEPT.

SQL> CREATE OR REPLACE function Find_Grade (p_empno in emp.empno%type) 2 RETURN number 3 is 4 v_grade salgrade. sinon.--appel de la fonction SQL> print H_grade H_GRADE --------4 99 . 12 exception 13 when no_data_found then 14 return(-1). SQL> var H_grade number.FONCTIONS Stockées ‡ Exemple Find_Grade qui retourne le grade de salaire d¶un empno s¶il existe. 5 begin 6 select grade 7 into v_grade 8 from emp. salgrade 9 where empno = p_empno and p_empno is not null 10 and sal between losal and hisal. SQL> execute :H_grade := find_grade(7788). 15 end Find_grade.grade%type. 11 return (v_grade).±1 .

CREATE et DROP : Commandes du LDD.Suppression de sous-programmes stockés sous‡ ‡ Suppression d¶une FONCTION/PROCEDURE DROP {PROCEDURE | FUNCTION} nompf . !!! 2. 100 . Remarques 1. Modes de passage de paramètres identiques aux sousprogrammes non stockés.

. local Sous-Programme Local Stocké sous forme compilée : Compilé avec son bloc parent. le sous-programme sera compilé à chaque fois Appelable par tout bloc Appelable uniquement dans le Utilisateur ayant le privilège bloc parent Exécute sur le sous programme . . immédiatement exécutable Si le bloc est exécuté plusieurs fois.. 101 .SousSous-programmes stockés versus soussousprogrammes locaux ‡ Comparaison S/Pg. stocké Sous-Programme Stocké et S/Pg.

± SQL> GRANT EXECUTE ON Lib_Jour TO B.SousSous-programmes et privileges ‡ Le privilège EXECUTE Le propriétaire d¶un s/pg stocké ou d¶un package peut autoriser d¶autres utilisateurs à s¶en servir en leur accordant le privilège EXECUTE : ± GRANT EXECUTE ON {fonct | proc | pkg} TO username . 102 .

Ce concept peut être énoncé par la règle : Règle : Un s/pg s¶exécute sous les privilèges de son propriétaire.SousSous-programmes et privileges ‡ Privilège Execute : Cas d¶objets de même nom Si UserB possède une table de même nom T1. quelle table sera modifiée ? C¶est UserA. 103 .T1.SOUSPROG. Lorsque UserB appelle UserA.

SousSous-programmes et Role ‡ Octroi de Privilèges sans ROLE GRANT SELECT GRANT EXECUTE ON T2 ON F TO UserB . permet à UserB de compiler avec succès son sous programme 104 . TO UserB .

d¶où : Règle : Un s/pg s¶exécute sous les privilèges attribués explicitement (non à travers un ROLE) à son propriétaire 105 . GRANT SELECT ON T2 TO My_Role. GRANT My_Role TO UserB . ne marchera pas .SousSous-programmes et Role ‡ Octroi de Privilège à travers un ROLE GREATE ROLE My_Role. GRANT EXECUTE ON F TO My_Role.

Le package DBMS_OUTPUT 106 .Plan ‡ Section 3 : Les packages 1. Structure d¶un package 2. Développement d¶un package 3.

réunit des fonctions et des procédures stockées Composé de 2 parties : ‡ Package Specification : déclarative variables globales. types prototypes de fonctions et des procédures ‡ Package Body : Description complète des fonctions/procédures globales § BEGIN optionnelle Déclaré en 2 phases : 107 .Structure d¶un package Progiciel. Exceptions. curseurs.

Exceptions.Prototypes des Fonctions / Procédures Globales prototype1. 108 . -.Développement d¶un package CREATE OR REPLACE PACKAGE pkg_name AS -. END [pkg_name]...Déclaration variables Globales.. prototype2. prototype n. Curseurs . ..

Développement d¶un package CREATE OR REPLACE PACKAGE BODY pkg_name AS -. 109 .Corps des Fonctions / Procédures Globales BEGIN -.optionnelle Commandes à exécuter une seule fois suite à votre premier appel du package (initialisation de variables par des valeurs calculées) END [pkg_name].

number(3).Déclaration variables Globales G_nb_emp G_nb_dept G_nb_MANAGERS G_avg_sal number.grade%type.empno%type) return salgrade. number(2). function get_grade(p_empno in emp. number(2).Prototypes des Fonctions / Procédures Globales function get_sal(p_empno in emp. END pkg_EMP. -.sal%type. function get_nb_emp_exceeds_avg_sal return number.Développement d¶un package ‡ Exemple CREATE OR REPLACE PACKAGE pkg_EMP AS -.empno%type) return emp. 110 .

ou une exception utilisateur END IF. EXCEPTION when no_data_found then raise_application_error ( -20000. µN° Employé ' || p_empno || ' Non Trouvé ou non renseigné').sal%type IS v_sal number .Développement d¶un package CREATE OR REPLACE PACKAGE BODY Pkg_EMP IS Function get_sal (p_empno in emp. return null. select sal into v_sal from emp where empno =p_empno. 111 . return v_sal. -.empno%type) return emp. BEGIN IF p_empno is not null THEN RAISE NO_DATA_FOUND. END get_sal.

return null. 112 . EXCEPTION when no_data_found then raise_application_error (-20001. return v_grade.grade%type. salgrade where empno = p_empno and p_empno is not null and sal between losal and hisal. 'Grade de Salaire non trouvé pour Employé n° '||p_empno).empno%type) return salgrade.Développement d¶un package Function get_grade(p_empno in emp. END get_grade.grade%type IS v_grade salgrade. BEGIN select grade into v_grade from emp .

113 . return null. END get_nb_emp_exceeds_avg_sal . BEGIN select count(*) into v_nb from emp where sal > G_avg_sal.utilisation var Globale EXCEPTION when no_data_found then raise_application_error (-20001.Développement d¶un package Function get_nb_emp_exceeds_avg_sal Return number IS v_nb integer. -. 'Erreur '). return v_nb.

-.Initialiser la variable G_nb_MANAGERS select count(*) into G_nb_MANAGERS from emp where upper(job) = 'MANAGER'.Initialiser la variable G_nb_emp select count(*) into G_nb_emp from emp.Initialiser la variable G_avg_sal select avg(sal) into G_avg_sal from emp.Développement d¶un package BEGIN -. -. -. 114 . END pkg_EMP.Initialiser la variable G_nb_dept select count(*) into G_nb_dept from dept.

Développement d¶un package ‡ Intérêt des packages . tous ses composants seront chargés en mémoire pour être directement disponibles. cette technique améliore les temps de réponse comparativement à l¶usage de sous programmes stockés où chacun est cherché individuellement sur demande. 115 . à des sous programmes stockés : ‡ A la première utilisation du package./.

get_sal(7788). 116 . Exemple BEGIN DBMS_OUTPUT. END.get_sal(7788) ).PUT_LINE ('G nb dept : ' ||PKg_emp. END. ou Execute :h_sal := PKg_emp.g_nb_dept ).PUT_LINE (µSalaire : µ ||PKg_emp. Les variables globales du package peuvent être référencées : BEGIN DBMS_OUTPUT.APPEL des s/pg d¶un package Préfixer par le nom du package.

5. 3. Introduction Utilité des déclencheurs Caractéristiques des déclencheurs Description d¶un déclencheur Usage Des Prédicats de Déclencheurs : INSERTING.Plan Chapitre 5 : Déclencheurs de BD 1. Gestion des déclencheurs 117 . UPDATING et DELETING 6. 4. 2.

Introduction ‡ On appelle déclencheur (trigger) un traitement qui se déclenche suite à un événement ‡ Dans une programmation traditionnelle se faisait par un appel de sous programme ‡ Il existe deux types de déclencheurs : ± Des déclencheurs applicatifs crées et manipulés au niveau d¶une application ± Des déclencheurs de bases de données stockés dans le dictionnaire de données du SGBD et associés à des événements sur des tables 118 .

«.«) ± Mettre en oeuvre une politique de sécurité complexe (par exemple. garder trace mises à jour douteuses. MAJ du stock suite à une entrée. déclenchement d¶une demande de réapprovisionnement à la suite d¶une insuffisance de stock.Utilité des déclencheurs ‡ Les déclencheurs sont utiles pour plusieurs fins : ± Implémenter certaines règles de métier du SI de l¶organisation (par exemple. interdire des modifications des données à certains utilisateurs. 119 .

120 .Caractéristiques des déclencheurs ‡ Les Triggers ressemblent aux sous programmes stockés sur les points suivants : ± Sont des blocs PL/SQL nommés ± Objets stockés dans Oracle sous forme de code source et pcode (exécutable) ‡ Mais ils en diffèrent sur les points suivants : ± Liés à un événement : exécution implicite ± Ne sont pas paramétrables ± Peuvent être désactivés ± Etc.

Description d¶un déclencheur ‡ Eléments de description Un trigger est défini à travers les éléments suivants : Elément Nom_Trigger Nom_Table Valeurs possibles Choisie par développeur Nom d¶une table le Explication Identifiant du déclencheur La table sur laquelle le trigger est défini. ou DELETE Séquencement BEFORE ou AFTER le séquencement du (timing) par rapport à son Avec BEFORE (AFTER). déclencheur l¶événement du Evénement INSERT ou UPDATE. le trigger sera déclenché Evénement déclenchant l¶exécution trigger : commande LMD ou une combinaison utilisant OR Caractérise déclencheur événement. Si l¶événement est exécuté sur cette table. 121 . le est lancé avant (après) que déclenchant ne soit exécuté.

Description d¶un déclencheur ‡ Niveaux de déclenchement Il existe deux niveaux de déclenchement : 1. le déclencheur est crée à l¶état actif (ENABLE) 122 . Niveau instruction (statement level trigger) 2. Après une compilation correcte. Niveau ligne (row level trigger) (1) : un déclencheur de niveau 1 s¶exécute une seule fois Création : la commande de création d¶un déclencheur permet sa compilation et son stockage dans la métabase.

. curseurs. 123 . records.Gestionnaires d¶exceptions END [nom_Trigger ].traitement EXCEPTION .Description d¶un déclencheur ‡ Création d¶un TRIGGER CREATE [ OR REPLACE ] TRIGGER nom_Trigger { BEFORE | AFTER } événement ON nom_Table DECLARE -.« BEGIN .déclarations variables..

Description d¶un déclencheur ‡ Déclencheur de Niveau ligne (row level trigger) Un déclencheur de ligne s¶exécute une fois pour chaque n-uplet affecté par l¶événement déclanchant.traitement EXCEPTION ..déclarations variables. 124 .. ‡ Création d¶un TRIGGER CREATE [OR REPLACE] TRIGGER nom_Trigger { BEFORE | AFTER } événement ON nom_Table FOR EACH ROW [WHEN condition] [REFERINCING {[old [AS] nom_old] | New [AS] nom_new]}] DECLARE -.Gestionnaires d¶exceptions END [nom_Trigger ].« BEGIN . curseurs. records.

Description d¶un déclencheur For each row Clause optionnelle. Autrement il est de niveau instruction Option de la clause For each Row (valable uniquement pour les triggers de niveau ligne). si utilisée le déclencheur spécifié sera de niveau ligne. introduit une condition selon laquelle le corps du déclencheur peut être exécuté ou simplement abandonné Permet de changer les noms standards des pseudo records OLD et NEW par de nouveaux noms nom_old et nom_new Condition Referencing 125 .

Exemples Ecrire un trigger de BD qui affiche un message à la suite de la suppression d¶un dept Choix des composants du trigger Nom Evénement Séquencement Niveau Table TRG_DEL_DEPT DELETE BEFORE (ou AFTER) Ligne DEPT 126 .Description d¶un déclencheur ‡ 1.

TRG0 : Dépt supprimé 1 ligne(s) supprimée(s).ou bien BEFORE -. 127 -.Description d¶un déclencheur CREATE OR REPLACE TRIGGER TRG_DEL_DEPT AFTER DELETE ON DEPT FOR EACH ROW BEGIN DBMS_OUTPUT.de niveau n-uplet . END TRG_DEL_DEPT.PUT_LINE(µTRG0 : Dépt supprimé¶). Test : SQL> delete from dept where deptno NOT IN (Select deptno from emp).

Si aucune ligne n¶est affectée alors aucun message affiché ± Utiliser un trigger de niveau instruction pour exécuter le corps du déclencheur une seule fois quelque soit le nombre de lignes affectées (même 0).Description d¶un déclencheur ‡ Remarques ± Comme il s¶agit d¶un µRow level Trigger¶ le corps du déclencheur sera exécuté avec chaque n-uplet affecté par l¶événement déclenchant (DELETE). Si aucune ligne n¶est affectée alors le message sera affiché. 128 .

129 . Test du trigger : SQL> delete from dept where deptno is null.Put_Line(µTRG_DEL_DEPT_Niv_Ins Déclenché¶). TRG_DEL_DEPT_Niv_Ins Déclenché 0 ligne(s) supprimée(s).ou bien BEFORE ON DEPT BEGIN DBMS_OUTPUT.Description d¶un déclencheur ‡ Exemple de Trigger de niveau instruction CREATE OR REPLACE TRIGGER TRG_DEL_DEPT_Niv_Ins AFTER DELETE -. END TRG_DEL_DEPT_Niv_Ins.

Description d¶un déclencheur ‡ Les Pseudo-records : old et : new ‡ Un trigger de niveau ligne se déclenche une fois avec chaque n-uplet traité par l¶événement du trigger ‡ A l¶intérieur d¶un trigger de niveau ligne. PL/SQL le permet par le biais des 2 pseudorecords :old et :new de même structure que la table sur laquelle le trigger est défini. on a souvent besoin d¶accéder aux données du n-uplet en cours de manipulation. 130 .

131 . ‡ Utilisables dans les curseurs implicites et explicites.Description d¶un déclencheur Evénement OLD NEW INSERT Tous les champs sont nulls Valeurs à insérer en provenance de la commande INSERT qui a déclenché le trigger Nouvelles valeurs après UPDATE UPDATE Valeurs originales du n-uplet avant UPDATE Valeurs Originales du n-uplet avant DELETE DELETE ‡ Non valables pour les triggers de niveau instruction.

loc). EXCEPTION When OTHERS THEN RAISE_APPLICATION_ERROR(-20001. END TRG_Archive_Dept. Exemple Ecrire un trigger qui enregistre dans la table ARCHIVE_DEPT chaque dept. Dname. Loc) VALUES (:old.dname.deptno. :old.Description d¶un déclencheur ‡ 1.¶Erreur dans Trigger Before Delete On DEPT¶) . Nom TRG_Archive_Dept Evénement DELETE Séquencement BEFORE Niveau Ligne Table DEPT CREATE OR REPLACE TRIGGER TRG_Archive_Dept BEFORE DELETE ON DEPT FOR EACH ROW BEGIN INSERT INTO ARCHIVE_DEPT (DEPTNO. 132 . Supprimé. :old.

:old. END .sysdate. nouv_sal) CREATE OR REPLACE TRIGGER TRG_Audit_Sal AFTER UPDATE OF SAL ON EMP FOR EACH ROW BEGIN INSERT INTO AUDIT_SAL VALUES (user. :old.--------. SQL> select * from audit_sal.--------SCOTT 18/04/02 7782 2450 3450 SCOTT 18/04/02 7839 5000 6000 SCOTT 18/04/02 7934 1300 2300 133 . :new. SQL> update emp set sal= sal + 1000 where deptno= 10. UTILISATE DATEMAJ EMPNO ANC_SAL NOUV_SAL --------. Empno.sal. EXCEPTION When others then null. 3 ligne(s) mise(s) à jour. anc_sal.sal).empno.Description d¶un déclencheur ‡ Exemple Ecrire un trigger de BD qui à la suite d¶une modification de salaire enregistre dans la table AUDIT_SAL (Utilisateur. date_maj.-------.--------.

Si utilisée. ‡ Les pseudo-record old et new sont autorisés dans clause WHEN mais sans le préfixe (:) la 134 .Description d¶un déclencheur ‡ La clause WHEN condition» Cette clause est valide uniquement pour les row-level triggers. la condition sera évaluée pour chaque ligne affectée par l¶événement du trigger. et le corps du trigger n¶est exécuté pour cette ligne que si l¶expression logique est vraie.

Description d¶un déclencheur ‡ Exemple 1 CREATE OR REPLACE TRIGGER TRG_B_IU_EMP BEFORE INSERT OR UPDATE of deptno ON EMP FOR EACH ROW WHEN (new. 3 ligne(s) mise(s) à jour.-------------.deptno.deptno = 40) BEGIN Update dept Set nb_emp = nvl(Nb_emp.0) + 1 Where deptno = :new. END TRG_B_U_EMP. Test du trigger : SQL> update emp set deptno where deptno = 40 = 10. SQL> select * from dept where deptno = 40.------------. DEPTNO DNAME LOC NB_EMP --------.--------40 OPERATIONS BOSTON 3 135 .

END TRG_B_Usal.sal). Test du trigger : EMPNO SAL COMM --------.320 = 20% de sal 136 .--------. CREATE OR REPLACE TRIGGER TRG_B_Usal BEFORE UPDATE OF SAL ON EMP FOR EACH ROW WHEN (upper(new. EMPNO SAL COMM --------.sal/:old.Description d¶un déclencheur ‡ Exemple 2 Modification systématique de la commission pour la fonction SALESMAN : Augmenter leur commission au prorata de leur augmentation du salaire. END IF.---------.sal.--------7499 1600 300 UPDATE EMP SET SAL = SAL+320 WHERE EMPNO = 7499.job) = µSALESMAN¶) BEGIN IF nvl(:old.--------.--------7499 1760 360 JOB SALESMAN -.comm *(:new.0)>0 THEN :new.comm := :old.

deptno = 40) THEN /* corps du trigger */ END IF. END TRG_B_U_EMP.Description d¶un déclencheur ‡ Remarques : ± La clause WHEN condition équivaut un test portant sur tout le corps du trigger ± Ainsi. 137 . TRG_B_UI_EMP peut être réécrit comme suit : CREATE OR REPLACE TRIGGER TRG_B_IU_EMP BEFORE INSERT OR UPDATE of deptno ON EMP FOR EACH ROW BEGIN IF (:new.

Description d¶un déclencheur ‡ Exemple Interdire les modifications sur la table EMP en dehors des horaires de travail supposés entre 8h à 17h. END. ¶Accès interdit en dehors des horaires de travail¶) . End IF . BEGIN If (to_number (to_char(sysdate. EXCEPTION WHEN E_ACCES_DENIED THEN RAISE_APPLICATION_ERROR (-20001. CREATE OR REPLACE TRIGGER TRG_Grant_Emp BEFORE UPDATE ON EMP DECLARE E_ACCES_DENIED EXCEPTION . 138 .¶HH24¶) ) NOT between 8 and 17) THEN RAISE E_ACCES_DENIED .

INSERT INTO Arch_dept (operation. ELSIF UPDATING THEN v_Operation:= 'U'. et DELETING ‡ Si l¶événement d¶un trigger utilise OR. UPDATING.loc. USER.deptno.new_loc) VALUES (v_Operation. old_deptno. :new.Usage Des Prédicats de Déclencheurs : INSERTING. :old. ELSE v_Operation:= 'D'. 139 . Les trois prédicats ci-dessus permettent de déterminer laquelle des opérations a déclenchée le trigger.loc). SYSDATE. changed_by.dname. END IF. END TRG_ARV_DEPT. old_dname. new_dname. :new. BEGIN IF INSERTING THEN v_Operation:= 'I'. timestamp. :new.dname. old_loc. :old. On peut alors tester dans le corps du trigger : CREATE OR REPLACE TRIGGER TRG_ARV_DEPT BEFORE INSERT OR DELETE OR UPDATE ON DEPT FOR EACH ROW DECLARE v_Operation CHAR(1).deptno. :old. le trigger se déclenchera alors par l¶une ou l¶autre des commandes LMD.new_deptno.

select * from arch_dept.'gestion'. et DELETING Test du Trigger : insert into dept values (70. C CHANGED_ TIMESTAM OLD_DEPTNO OLD_DNAME OLD_LOC NEW_DEPTNO NEW_DNAME . UPDATING.'FSEGS').-----------.---------.--------I SCOTT 18/04/02 70 gestion U SCOTT 18/04/02 70 gestion FSEGS 70 GESTION D SCOTT 18/04/02 70 GESTION FSEGS NEW_LOC FSEGS FSEGS 140 .Usage Des Prédicats de Déclencheurs : INSERTING.-------.---------. update dept set dname = upper (dname) where deptno =70.-------.-----------.---------.

TableName { ENABLE | DISABLE } ALL 141 . A la création un trigger est activé Un trigger désactivé (DISABLE) continue à exister dans le DD. ‡ ALTER TRIGGER triggerName { ENABLE |DISABLE } .Gestion des déclencheurs ‡ DROP TRIGGER triggerName . ‡ Affichage des erreurs de compilation SQL>SHOW ERRORS ‡ Activation/Désactivation de Tous les Triggers d¶une table ALTER TABLE TRIGGERS . ‡ Activation / Désactivation d¶un trigger Parfois il est préférable de désactiver un trigger que de le supprimer en vue de le réactiver ultérieurement.

CREATE OR REPLACE TRIGGER TRG_DENY_DELETE_EMP BEFORE DELETE ON EMP DECLARE E_DELETE_DENIED EXCEPTION . ‡ Exemple Ecrire un déclencheur qui Interdit la suppression d¶employés. EXCEPTION WHEN E_DELETE_DENIED THEN RAISE_APPLICATION_ERROR (-20002. 142 .Conclusion ‡ Lorsqu¶un trigger échoue (exception non traitée ou explicitement reconduite avec RAISE_APPLICATION_ERROR sa commande événement Echoue de même. 'Suppression d''Employées Non Autorisée') . BEGIN RAISE E_DELETE_DENIED. END.

Merci de Votre attention 143 .