Vous êtes sur la page 1sur 78

Administration des bases de données sur Oracle

11g

Chap 2 : PL/SQL

Faculté des Sciences et techniques –Tanger-


Département –génie informatique-
1
C.ing LSI2
Définition du langage PL/SQL

Le langage PL/SQL :

Procedural Language extension to SQL

• Langage standard d'accès aux données d'Oracle

• intègre de manière transparente les structures procédurales au


langage SQL

2
Définition du langage PL/SQL

Le PL/SQL fournit des structures procédurales telles que :

– Variables, constantes et types

– Structures de contrôle : les instructions conditionnelles et les boucles

– Programmes réutilisables écrits une fois et exécutés plusieurs fois

3
Structure d'un bloc PL/SQL

DECLARE (facultatif)
Variables, curseurs, exceptions définies par l'utilisateur

BEGIN (obligatoire)
- Instructions SQL
- Instructions PL/SQL

EXCEPTION (facultatif)
Actions à effectuer lorsque des erreurs se produisent

END; (obligatoire)

4
Types de bloc PL/SQL

5
Types de bloc PL/SQL

les blocs anonymes sont :

 des blocs non nommés,


 déclarés en ligne dans une application, à l'endroit où ils doivent être exécutés,
 compilés chaque fois que l'application est exécutée,
 ne sont pas stockés dans la base de données.

les sous-programmes Il s'agit de blocs PL/SQL nommés stockés dans la base


de données.

6
Structures de programme

Blocs anonymes Blocs PL/SQL anonymes imbriqués dans une application ou


exécutés de manière interactive

Procédures ou Blocs PL/SQL nommés, stockés dans une application ou une


Fonctions applicatives bibliothèque partagée Oracle Forms Developer ; ils acceptent
des paramètres et peuvent être appelés à plusieurs reprises par
leur nom

Procédures ou Blocs PL/SQL nommés, stockés sur le serveur Oracle ; ils


Fonctions stockées acceptent des paramètres et peuvent être appelés à plusieurs
reprises par leur nom

Déclencheurs Blocs PL/SQL associés à une table de base de données et


exécutés automatiquement lorsqu'ils sont déclenchés par
différents événements

7
Environnements de programmation PL/SQL

8
Créer un bloc anonyme

Le bloc anonyme obtient la valeur first_name de l'employé dont la valeur


employee_id est 100 et stocke cette valeur dans une variable nommée f_name.

9
Tester la sortie d'un bloc PL/SQL

Le langage PL/SQL ne permet pas les entrées-sorties. Par conséquent, nous


utilisons des packages Oracle prédéfinis pour l'entrée et la sortie.

Pour générer la sortie, vous devez effectuer les opérations suivantes :

1. • Activez la sortie dans iSQL*Plus avec la commande :


SET SERVEROUTPUT ON.

2. • Utilisez la procédure PUT_LINE du package DBMS_OUTPUT afin d'afficher


la sortie.

10
Tester la sortie d'un bloc PL/SQL

11
Utilisation des variables

Les variables peuvent être utilisées pour :

• le stockage temporaire de données


• la manipulation de valeurs stockées

Les noms :

– doivent commencer par une lettre


– peuvent inclure des lettres ou des chiffres
– peuvent inclure des caractères spéciaux,
– doivent présenter une longueur maximale de 30 caractères
– ne doivent pas être des mots réservés

12
Utilisation des variables

Syntaxe :

identifier [CONSTANT] datatype [NOT NULL] [:= | DEFAULT expr];

Exemples :

DECLARE
emp_hiredate DATE;
emp_deptno NUMBER(2) NOT NULL := 10;
location VARCHAR2(13) := 'Atlanta';
c_comm CONSTANT NUMBER := 1400;

13
Utilisation des variables

SET SERVEROUTPUT ON
DECLARE
Myname VARCHAR2(20);
BEGIN
DBMS_OUTPUT.PUT_LINE('My name is: '||Myname);
Myname := 'nabil';
DBMS_OUTPUT.PUT_LINE('My name is: '||Myname);
END;
/

SET SERVEROUTPUT ON
DECLARE
Myname VARCHAR2(20):= 'nabil';
BEGIN
Myname := 'noufal';
DBMS_OUTPUT.PUT_LINE('My name is: '||Myname);
END;

14
Utilisation des variables

Délimiteurs dans les littéraux de type chaîne

SET SERVEROUTPUT ON
DECLARE
event VARCHAR2(15);
BEGIN
event := q'!Father's day!';
DBMS_OUTPUT.PUT_LINE('3rd Sunday in June is : '||event);
event := q'[Mother's day]';
DBMS_OUTPUT.PUT_LINE('2nd Sunday in May is :'||event);
END;

15
Types de variable

Les types scalaires reçoivent une seule valeur.

Les types composés tels que les records, permettent de


définir des groupes de champs et de les manipuler dans des
blocs PL/SQL.

Les types LOB contiennent des valeurs, appelés aussi


locators, ils spécifient l’emplacement des Large Objets
(Images)

…

16
Types de variable

Types de données scalaires de base

VARCHAR2 (maximum_length)
NUMBER [(precision, scale)]
DATE
CHAR [(maximum_length)]
LONG

etc

17
Utilisation des variables

Exemples :

DECLARE
emp_job VARCHAR2(9);

count_loop BINARY_INTEGER := 0;

dept_total_sal NUMBER(9,2) := 0;

orderdate DATE := SYSDATE + 7;

c_tax_rate CONSTANT NUMBER(3,2) := 8.25;

valid BOOLEAN NOT NULL := TRUE;

18
L'attribut %TYPE

• est utilisé pour déclarer une variable en fonction :

– d'une définition de colonne de base de données


– d'une autre variable déclarée

• est préfixé avec :

– la table et la colonne de base de données


– le nom de la variable déclarée

L'attribut %TYPE est le plus souvent utilisé lorsque la valeur stockée dans la
variable est issue d'une table de la base de données.

19
L'attribut %TYPE

Syntaxe :

identifier table.column_name%TYPE;

Exemples :

emp_lname employees.last_name%TYPE;

balance NUMBER(7,2);

min_balance balance%TYPE := 1000;

20
Utilisation des variables

Les types composés (appelés aussi collections) sont les


suivants : TABLE, RECORD, NESTED TABLE et
VARRAY

utiliser le type RECORD pour traiter des données en


relation mais non similaire en tant qu’unité logique.

Utiliser le type TABLE pour référencer et manipuler


des ensembles de données en tant qu’objet unique

21
Utilisation des variables

Variables de substitution

Elles sont utilisées pour autoriser la saisie de l'utilisateur lors de


l'exécution.

• Elles sont référencées dans un bloc PL/SQL avec une esperluette.

• Elles sont utilisées afin d'éviter le codage en dur des valeurs pouvant être
obtenues lors de l'exécution.

22
Utilisation des variables

Exemple
VARIABLE emp_salary NUMBER
SET AUTOPRINT ON
DECLARE
empno NUMBER(6):=&empno;
BEGIN
SELECT salary INTO :emp_salary
FROM employees WHERE employee_id = empno;
END;

23
Ecrire des instructions exécutables

les délimiteurs

24
Ecrire des instructions exécutables
Opérateurs en langage PL/SQL

Incrémenter le compteur pour une boucle :


loop_count := loop_count + 1;

• Définir la valeur d'un indicateur booléen :


good_sal := sal BETWEEN 50000 AND 150000;

25
Ecrire des instructions exécutables

Blocs imbriqués

DECLARE
outer_variable VARCHAR2(20):='GLOBAL VARIABLE';

BEGIN
DECLARE
inner_variable VARCHAR2(20):='LOCAL VARIABLE';
BEGIN
DBMS_OUTPUT.PUT_LINE(inner_variable);
DBMS_OUTPUT.PUT_LINE(outer_variable);
END;

DBMS_OUTPUT.PUT_LINE(outer_variable);

END;/

26
Portée et visibilité des variables
DECLARE
father_name VARCHAR2(20):='Patrick';
date_of_birth DATE:='20-Apr-1972';
BEGIN
DECLARE
child_name VARCHAR2(20):='Mike';
date_of_birth DATE:='12-Dec-2002';
BEGIN
DBMS_OUTPUT.PUT_LINE('Father''s Name: '||father_name);
DBMS_OUTPUT.PUT_LINE('Date of Birth: '||date_of_birth);
DBMS_OUTPUT.PUT_LINE('Child''s Name: '||child_name);
END;
DBMS_OUTPUT.PUT_LINE('Date of Birth: '||date_of_birth);
END;
/

27
Qualifier un identificateur

<<outer>>
DECLARE
father_name VARCHAR2(20):='Patrick';
date_of_birth DATE:='20-Apr-1972';
BEGIN
DECLARE
child_name VARCHAR2(20):='Mike';
date_of_birth DATE:='12-Dec-2002';
BEGIN
DBMS_OUTPUT.PUT_LINE('Father''s Name: '||father_name);
DBMS_OUTPUT.PUT_LINE('Date of Birth: ‘||outer.date_of_birth);
DBMS_OUTPUT.PUT_LINE('Child''s Name: '||child_name);
DBMS_OUTPUT.PUT_LINE('Date of Birth: '||date_of_birth);
END;
END;

28
Instructions SELECT en langage PL/SQL

Syntaxe :
SELECT select_list
INTO {variable_name[, variable_name]…| record_name}
FROM table
[WHERE condition];

Liste comprenant au moins une colonne, où peuvent figurer des


select_list
expressions SQL, des fonctions de ligne ou des fonctions de groupe.

variable_name Variable scalaire contenant la valeur extraite.


record_name Enregistrement PL/SQL contenant les valeurs extraites.
table Nom de la table de base de données.
Comprend des noms de colonne, des expressions, des constantes et des
condition opérateurs de comparaison, ainsi que des variables et des constantes
PL/SQL.
29
Instructions SELECT en langage PL/SQL

Instructions SELECT en langage PL/SQL

• La clause INTO est obligatoire.


• Les interrogations doivent renvoyer une seule ligne.

Exemple :

SET SERVEROUTPUT ON
DECLARE
fname VARCHAR2(25);
BEGIN
SELECT first_name INTO fname
FROM employees WHERE employee_id=200;
DBMS_OUTPUT.PUT_LINE(' First Name is : '||fname);
END;
/

30
Instructions SELECT en langage PL/SQL

Exemple

Extrayez de la table employees les valeurs hire_date et salary de l'employé ayant


employee_id = 100.

DECLARE
emp_hiredate employees.hire_date
%TYPE;
emp_salary employees.salary
%TYPE;
BEGIN
SELECT hire_date, salary
INTO emp_hiredate, emp_salary
FROM employees
WHERE employee_id = 100;
END;

31
Instructions INSERT en langage PL/SQL

BEGIN
INSERT INTO employees
(employee_id, first_name, last_name, email, hire_date, job_id, salary)
VALUES
(employees_seq.NEXTVAL, 'Ruth', 'Cores‘, 'RCORES',sysdate, 'AD_ASST', 4000);
END;
/

Ajouter les informations relatives à un nouvel employé à la table EMPLOYEES.

32
Instructions UPDATE en langage PL/SQL

Exemple :
DECLARE
sal_increase employees.salary%TYPE := 800;
BEGIN
UPDATE employees
SET salary = salary + sal_increase
WHERE job_id = 'ST_CLERK';
END;
/

Augmenter le salaire de tous les employés chargés du contrôle des stocks.

33
Instructions DELETE en langage PL/SQL

Exemple :

Supprimez les lignes appartenant au departement_id 10 à partir de la table employees.

DECLARE
deptno employees.department_id%TYPE := 10;
BEGIN
DELETE FROM employees
WHERE department_id = deptno;
END;

34
Instructions MERGEE en langage PL/SQL

L'instruction MERGE permet d'insérer ou de mettre à jour des lignes dans une
table, en utilisant les données d'une autre table.

Chaque ligne est insérée ou mise à jour dans la table cible, en fonction d'une
condition d'équijointure.

35
Instructions MERGEE en langage PL/SQL

DECLARE
empno EMPLOYEES.EMPLOYEE_ID%TYPE := 100;
BEGIN
MERGE INTO copy_emp c
USING employees e
ON (e.employee_id = empno)
WHEN MATCHED THEN
UPDATE SET
c.first_name = e.first_name,
c.last_name = e.last_name,
c.email = e.email, WHEN NOT MATCHED THEN
c.phone_number = e.phone_number, INSERT VALUES(e.employee_id, e.first_name,
c.hire_date = e.hire_date, e.last_name,
c.job_id = e.job_id, e.email, e.phone_number, e.hire_date,
c.salary = e.salary, e.job_id,
c.commission_pct = e.commission_pct, e.salary, e.commission_pct, e.manager_id,
c.manager_id = e.manager_id, e.department_id);
c.department_id = e.department_id END;

36
Instructions MERGEE en langage PL/SQL

L'exemple présenté compare employee_id dans la table COPY_EMP à employee_id dans


la table employees.

Si une correspondance est trouvée, la ligne de la table COPY_EMP est mise à jour par
rapport à celle de la table employees.

Si la ligne est introuvable, elle est insérée dans la table copy_emp.

37
Les instructions de contrôle

Contrôler le flux
d'exécution

38
Instructions IF

Syntaxe : IF condition THEN


instructions;
[ELSIF condition THEN
instructions;]
[ELSE
instructions;]
END IF;
Exemple:
DECLARE
myage number:=31;
BEGIN
IF myage < 11
THEN
DBMS_OUTPUT.PUT_LINE(' I am a child ');
END IF;
END;
39
Instructions IF

Exemple:

SET SERVEROUTPUT ON
DECLARE
myage number:=31;
BEGIN
IF myage < 11
THEN
DBMS_OUTPUT.PUT_LINE(' I am a child ');
ELSE
DBMS_OUTPUT.PUT_LINE(' I am not a child ');
END IF;
END;

40
Expressions CASE

Syntaxe :

CASE selector

WHEN expression1 THEN result1


WHEN expression2 THEN result2
...
WHEN expressionN THEN resultN

[ELSE resultN+1]

END;

41
Expressions CASE

Exemple:
SET SERVEROUTPUT ON
DECLARE
grade CHAR(1) := UPPER('&grade');
appraisal VARCHAR2(20);
BEGIN
appraisal :=
CASE grade
WHEN 'A' THEN 'Excellent'
WHEN 'B' THEN 'Very Good'
WHEN 'C' THEN 'Good'
ELSE 'No such grade'
END;
DBMS_OUTPUT.PUT_LINE ('Grade: '|| grade || ‘ Appraisal ' || appraisal);
END;

42
instruction LOOP

Syntaxe :

LOOP -- initialisation
instruction1 -- instructions
...
EXIT [WHEN condition]; -- EXIT instruction
END LOOP; -- fermeture de la boucle

43
Instruction LOOP

Exemple:
DECLARE
countryid locations.country_id%TYPE := 'CA';
loc_id locations.location_id%TYPE;
counter NUMBER(2) := 1;
new_city locations.city%TYPE := 'Montreal';
BEGIN
SELECT MAX(location_id) INTO loc_id FROM locations
WHERE country_id = countryid;
LOOP
INSERT INTO locations(location_id, city, country_id)
VALUES((loc_id + counter), new_city, countryid);
counter := counter + 1;
EXIT WHEN counter > 3;
END LOOP;
END;
/

44
Instruction WHILE

Syntaxe :

WHILE condition LOOP


instruction1;
instruction2;
...
END LOOP;

45
instruction WHILE

Exemple:
DECLARE
countryid locations.country_id%TYPE := 'CA';
loc_id locations.location_id%TYPE;
new_city locations.city%TYPE := 'Montreal';
counter NUMBER := 1;
BEGIN
SELECT MAX(location_id) INTO loc_id FROM locations
WHERE country_id = countryid;

WHILE counter <= 3 LOOP


INSERT INTO locations(location_id, city, country_id)
VALUES((loc_id + counter), new_city, countryid);
counter := counter + 1;
END LOOP;
END;

46
instruction FOR

Syntaxe :

FOR counter IN borne_inférieure..borne_supérieure LOOP

instruction1;
instruction2;
...

END LOOP;

47
instruction FOR

Exemple:
DECLARE
countryid locations.country_id%TYPE := 'CA';
loc_id locations.location_id%TYPE;
new_city locations.city%TYPE := 'Montreal';
BEGIN
SELECT MAX(location_id) INTO loc_id
FROM locations
WHERE country_id = countryid;
FOR i IN 1..3 LOOP

INSERT INTO locations(location_id, city, country_id)


VALUES((loc_id + i), new_city, countryid );

END LOOP;
END;

48
Boucles imbriquées et Etiquettes

BEGIN
<<Maitre_loop>>
LOOP
v_counter := v_counter+1;
EXIT WHEN v_counter>10;
<<Detail_loop>>
LOOP
...
EXIT Maitre_loop WHEN total_done = 'YES';
-- Quitter les 2 boucles
EXIT WHEN Detail_done = 'YES';
-- Quitter la boucle détail seulement
...
END LOOP Detail_loop;
...
END LOOP Maitre_loop;
END;
/
49
Les Curseurs

50
Curseurs Implicites et Explicites

• Le serveur Oracle utilise des zones de travail appelées zones


SQL privées pour exécuter les instructions SQL et pour stocker
les informations en cours de traitement.

• Chaque instruction SQL exécutée par le serveur Oracle a son


propre curseur individuel qui lui est associé :

– Curseurs implicites : déclarés pour toutes les instructions LMD et


SELECT PL/SQL

– Curseurs explicites : déclarés et nommés par le programmeur

51
Curseurs Explicites

 Les curseurs explicites sont utilisées pour traiter individuellement


chaque ligne retournée par une instruction SELECT.

 Cet ensemble de lignes retournées par une requête multi-lignes est


appelé Ensemble Actif .

 Sa taille est égale au nombre de lignes répondant aux critères de


recherche.

 Ceci permet à votre programme de traiter les enregistrements de la


requête ligne à ligne.

 Un programme PL/SQL ouvre un curseur, traite les lignes retournées


par la requête, et ensuite ferme le curseur.

 Le curseur marque la position courante dans l’Ensemble Actif.

52
Curseurs Explicites
SET SERVEROUTPUT ON;
DECLARE
v_emp scott.emp%rowtype;
CURSOR c_emp IS
SELECT ename, job
FROM scott.emp
WHERE job = 'SALESMAN';
BEGIN
OPEN c_emp;
IF c_emp%ISOPEN =TRUE THEN
dbms_output.put_line('Curseur is OPEN');
END IF;

LOOP
FETCH c_emp INTO v_emp.ename, v_emp.job;
IF c_emp%NOTFOUND THEN
IF c_emp%ROWCOUNT = 0 THEN
dbms_output.put_line('Job = SALESMAN INNEXISTANT');
ELSE
dbms_output.put_line('Fin De Boucle, Nbr Enreg = ' || c_emp%ROWCOUNT);
END IF;
EXIT;
ELSIF c_emp%FOUND THEN
dbms_output.put_line('Name = '||v_emp.ename || ' Job = ' || v_emp.job);
END IF;
END LOOP;
CLOSE c_emp;
IF c_emp%ISOPEN = FALSE THEN
dbms_output.put_line('Curseur is CLOSE');
END IF;
END;

53
Contrôler les Curseurs Explicites

si OUI, Retourner
Oui à FETCH

DECLARE OPEN
OPEN Existence? Close
Close
FETCH
FETCH
Cursor Cursor
Cursor Cursor
Cursor
Non

Créer une zone SQL Identifier Charger la ligne Tester l’existence Libérer l’ensemble
nommée l’ensemble actif courante dans des de lignes actif
de lignes variables

54
Contrôler les Curseurs Explicites

 Déclarer le curseur en le nommant et en définissant la requête à


exécuter (DECLARE).

 Ouvrir le curseur. L’instruction OPEN exécute la requête. Les lignes


de l’Ensemble Actif sont disponibles pour être traitées.

 Ramener les données du curseur.


 L’instruction FETCH charge la ligne courante du curseur dans des
variables.
 Chaque fetch fait avancer le pointeur du curseur vers la ligne suivante dans
l’Ensemble Actif.
 Après chaque fetch il faut tester si le curseur contient encore des lignes.
 Si des lignes sont trouvées, le fetch charge la ligne courante dans des
variables,
 sinon il faut fermer le curseur.

 Fermer le curseur. L’instruction CLOSE libère l’Ensemble Actif de


lignes
55
Déclarer un Curseur

Pas de clause INTO dans la déclaration du curseur.

Syntaxe :
CURSOR cursor_name IS
select_statement;

Exemple:
DECLARE
CURSOR emp_cursor IS
SELECT empno, ename
FROM emp;
CURSOR dept_cursor IS
SELECT *
FROM dept
WHERE deptno = 10;
BEGIN
56
Ouvrir un Curseur

L’instruction OPEN

 curseur pointe à présent sur la première ligne de l’Ensemble Actif.

 Si la requête ne retourne pas de ligne, aucune exception n’est signalée.

 Utilisez les attributs du curseur pour tester le résultat après affectation.

Syntaxe

OPEN cursor_name;

57
L’instruction FETCH

L’instruction FETCH ramène les lignes de l’Ensemble Actif une


par une

 Après chaque fetch, le pointeur du curseur se place devant la ligne


suivante de l’Ensemble Actif

 Inclure le même nombre de variables dans la clause INTO du


FETCH que de colonnes dans le SELECT.

Syntaxe

FETCH cursor_name INTO [variable1, variable2, ...]


| record_name];

58
L’instruction FETCH

FETCH emp_cursor INTO v_empno, v_ename


...
OPEN defined_cursor;
LOOP
FETCH defined_cursor INTO defined_variables
EXIT WHEN ...;
...
-- Traiter les données ramenées
...
END;

59
Fermer un Curseur

• L’instruction CLOSE

 L’instruction CLOSE désactive le curseur, et l’Ensemble


Actif n’est plus défini
 Fermer le curseur après avoir achevé le traitement de
l’instruction SELECT
 Cette étape permet au curseur d’être ré-ouvert, si
nécessaire

Syntaxe

CLOSE cursor_name;

60
Les Attributs d’un Curseur Explicite

quatre attributs pour obtenir les informations de statut sur le


curseur

 %ISOPEN Boolean Evalué à TRUE si le curseur est ouvert.


 %NOTFOUND Boolean Evalué à TRUE si le dernier fetch n’a
pas retourné de ligne.
 %FOUND Boolean Evalué à TRUE si le dernier fetch a
retourné une ligne ;
 %ROWCOUNT Number Contient le nombre total de lignes
retournées jusqu’ici.

61
Les Attributs d’un Curseur Explicite

– Traitez plusieurs lignes à partir d’un curseur explicite en


utilisant une boucle.
– Utilisez l’attribut %NOTFOUND pour tester l'échec de la
dernière affectation.
– Utilisez les attributs explicites du curseur pour tester le succès
de chaque affectation

IF NOT emp_cursor%ISOPEN THEN


OPEN emp_cursor;
END IF;
LOOP
FETCH emp_cursor...
Les Attributs %NOTFOUND et %ROWCOUNT

62
Curseurs et Records
Pour traiter les lignes de l’Ensemble Actif,
– faire le fetch dans le Record.
– les valeurs de la ligne sont chargées directement dans les
champs correspondant du record.
– La variable record peut être déclarée en utilisant l’attribut
%ROWTYPE

DECLARE
CURSOR emp_cursor IS
SELECT empno, ename
FROM emp;
emp_record emp_cursor%ROWTYPE;
BEGIN
OPEN emp_cursor;
LOOP
FETCH emp_cursor INTO emp_record;
...
63
Curseur dans une boucle FOR

• Ne déclarez pas le record qui contrôle la boucle. Sa portée


est seulement dans la boucle.

• Testez les attributs du curseur pendant la boucle, si


nécessaire.

FOR record_name IN cursor_name LOOP


statement1;
statement2;
...
END LOOP;

64
Curseur dans une boucle FOR
Exemple:

Declare
-- Déclaration du curseur
CURSOR C_EMP IS
Select * From EMP
Where job = 'CLERK‘ ;
Begin
For Cur IN C_EMP Loop
dbms_output.put_line( To_char( Cur.empno ) || ' - ' || Cur.ename ) ;
End loop ;
End ;
/
7369 - SMITH
7876 - ADAMS
7900 - JAMES
7934 - MILLER

65
Curseur dans une boucle FOR

Exemple:

DECLARE
CURSOR emp_cursor IS
SELECT ename, deptno
FROM emp;
BEGIN
FOR emp_record IN emp_cursor LOOP
-- un open et un fetch implicites ont lieu
IF emp_record.deptno = 30 THEN
...
END LOOP; -- un close implicite a lieu
END;

66
Exemple:

• Ramenez les employés un par un et affichez la liste


de ces employés travaillant actuellement dans le
département des ventes

67
Les Exceptions

68
Traitement des Exceptions

• Qu’est-ce qu’une exception ?


– Un identifiant PL/SQL, de type erreur, déclenché pendant l’exécution du
bloc

• Comment est-elle déclenchée ?


– Implicitement, par une erreur Oracle
– Explicitement, par le programme

• Comment la traiter ?
– En l’interceptant dans le traitement des exceptions
– En la propageant à l’environnement appelant

69
Traitement des Exceptions

• Une exception est un identifiant PL/SQL généré au cours de


l’exécution d’un bloc qui termine le corps principal des
instructions.

• Un bloc s’arrête quand une exception PL/SQL est déclenchée,


cependant vous pouvez spécifier un traitement dans les
exceptions afin de réaliser des instructions finales.

70
Traitement des Exceptions

• Deux méthodes pour déclencher une Exception

– Lorsqu’une erreur Oracle se produit,


• l’exception associée est émise automatiquement. Par exemple, si
l’erreur ORA-01403 survient car un SELECT n’a ramenée aucune
ligne, alors le PL/SQL émet l’exception NO_DATA_FOUND.

– Produire explicitement une exception en insérant une


instruction RAISE dans un bloc.

– L’exception ainsi émise peut être soit définie par l’utilisateur,


soit pré-définie.

71
Interception d’une Exception

• le traitement se débranche au sous-programme correspondant


dans la section Exception du bloc

• Si le PL/SQL traite convenablement l’exception, alors elle


n’est pas propagée au bloc supérieur ou vers l’environnement
appelant.

72
Interception d’une Exception

Syntaxe :
EXCEPTION
WHEN exception1 [OR exception2 . . .] THEN
instruction1;
instruction2;
...
[WHEN exception3 [OR exception4 . . .] THEN
instruction1;
instruction2;
. . .]
[WHEN OTHERS THEN
instruction1;
instruction2;
. . .]

73
Erreurs Oracle pré-définies

• Exemple d’exceptions pré-définies :


– NO_DATA_FOUND
– TOO_MANY_ROWS
– INVALID_CURSOR
– ZERO_DIVIDE
– …

74
Interception des erreurs Oracle pré-définies

BEGIN SELECT ... COMMIT;


EXCEPTION
WHEN NO_DATA_FOUND THEN
instruction1;
instruction2;
WHEN TOO_MANY_ROWS THEN
instruction1;
WHEN OTHERS THEN
instruction1;
instruction2;
instruction3;
END;
75
Erreurs Oracle non pré-définies

• Intercepter une erreur de violation de contraintes (Erreur


Oracle –2292)
DECLARE
v_deptno dept.deptno%TYPE := &p_deptno;
BEGIN
DELETE FROM dept
WHERE deptno = v_deptno;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE=2292 THEN
DBMS_OUTPUT.PUT_LINE('Suppression
Impossible du dep:'||TO_CHAR(v_deptno)||'Employés existant ');
END IF;
END;
76
Exceptions définies par l’utilisateur

DECLARE
e_invalid_product EXCEPTION;
BEGIN
UPDATE product
SET descrip = '&product_description'
WHERE prodid = &product_number;
IF SQL%NOTFOUND THEN
RAISE e_invalid_product;
END IF;
COMMIT;
EXCEPTION
WHEN e_invalid_product THEN
DBMS_OUTPUT.PUT_LINE('Numéro de produit invalide.');
END;

77
Fonctions d’interception des Erreurs

DECLARE
v_error_code NUMBER;
v_error_message VARCHAR2(255);
BEGIN
...
EXCEPTION
...
WHEN OTHERS THEN
ROLLBACK;
v_error_code := SQLCODE ;
v_error_message := SQLERRM ;
INSERT INTO erreurs VALUES(v_error_code,v_error_message);

78

Vous aimerez peut-être aussi