Vous êtes sur la page 1sur 143

ORACLE-PL/SQL

UNIVERSITE INUKA
.
Troisième année, 2019-2020
Fichier et Base de données

Prof. Andy PIERRE


andy.pierre@gmail.com

1 Prof: Andy PIERRE, M.Sc


Le langage PL/SQL
1. Introduction
2. Structure d’un bloc PL/SQL
3. Variables et Types de Données en PL/SQL
4. Traitement des données en PL/SQL
5. Procédures et fonctions en PL/SQL
6. Les curseurs en PL/SQL
7. Les Packages en PL/SQL
8. Utilisation des Triggers en ORACLE
9. Gestion des erreurs en PL/SQL

2 Prof: Andy PIERRE, M.Sc


1. INTRODUCTION
Procedural Language/SQL (PL/SQL) est une extension procédurale au SQL propre à
Oracle. Le PL/SQL possède les caractéristiques des langages de programmation procé-
duraux, tels que le C .

- Le PL/SQL est un puissant langage de traitement des transactions.

-Le PL/SQL est un langage hybride : il utilise des ordres SQL pour accéder à la base de
données et des instructions PL/SQL pour contrôler les ordres SQL afin de traiter de façon
explicite des données.

-Le PL/SQL permet d'inclure la manipulation des données et les ordres SQL dans des blocs
structurés et dans des unités procédurales de code.

3 Prof: Andy PIERRE, M.Sc


1. INTRODUCTION
SQL : langage ensembliste et non procédural

PL/SQL : langage procédural qui intègre des ordres SQL de gestion


de la base de données

Instructions SQL intégrées dans PL/SQL :


- SELECT
- INSERT, UPDATE, DELETE
- COMMIT, ROLLBACK, SAVEPOINT
- TO_CHAR, TO_DATE, UPPER, ...

4 Prof: Andy PIERRE, M.Sc


1. INTRODUCTION
Instructions spécifiques à PL/SQL :
- définition de variables et de Constantes
- traitements conditionnels
- traitements répétitifs
- traitement des curseurs
- traitement des Exceptions

5 Prof: Andy PIERRE, M.Sc


1. INTRODUCTION
Les fonctionnalités du moteur PL/SQL
Un serveur Oracle prenant en charge PL/SQL est appelé serveur Oracle avec extension
procédurale.

Les blocs PL/SQL sont transmis de l'application au moteur PL/SQL du serveur Oracle.
Ensuite, le moteur PL/SQL fractionne les instructions SQL du bloc en instructions
séparées, puis les envoie au moteur SQL.

Si les blocs sont fractionnés en instructions SQL, un seul transfert est nécessaire entre
l’application et le serveur Oracle ce qui permet de réduire le trafic réseau et
d’augmenter de façon significative les performances, en particulier en architecture
client/serveur.

6 Prof: Andy PIERRE, M.Sc


1. INTRODUCTION

7 Prof: Andy PIERRE, M.Sc


Le langage PL/SQL
1. Introduction
2. Structure d’un bloc PL/SQL
3. Variables et Types de Données en PL/SQL
4. Traitement des données en PL/SQL
5. Procédures et fonctions en PL/SQL
6. Les curseurs en PL/SQL
7. Les Packages en PL/SQL
8. Utilisation des Triggers en ORACLE
9. Gestion des erreurs en PL/SQL

8 Prof: Andy PIERRE, M.Sc


2. Structure d’un bloc PL/SQL
Les blocs PL/SQL
PL/SQL est un langage structuré en blocs : les instructions entre lesquelles il
existe un lien logique sont regroupées en blocs.
Un bloc de base PL/SQL peut contenir trois sections :
Elle contient toutes les déclarations des variables, constantes,
curseurs et exceptions définies par l’utilisateur et utilisées dans la
Section déclarative section exécutable. La section déclarative est facultative et doit
commencer par le mot clé DECLARE

Elle contient des instructions SQL permettant de manipuler les


données de la base de données et des instructions PL/SQL
Section exécutable permettant de manipuler les données d’un bloc. La section
exécutable est obligatoire et doit commencer par le mot clé BEGIN.

Elle spécifie les actions à effectuer lorsque des erreurs ou des


Section de traitement conditions anormales se produisent dans la section exécutable. La
des exceptions section de traitement des exceptions est facultative et doit
commencer par le mot clé EXCEPTION.

9 Prof: Andy PIERRE, M.Sc


2. Structure d’un bloc PL/SQL
Un bloc PL/SQL se termine par le mot-clé END suivi d’un point virgule.

Pour faciliter la lecture d’un bloc de code PL/SQL, chaque nouvelle instruction doit être
sur une nouvelle ligne et les différents niveaux des blocs doivent être mis en évidence
par des retraits.

[DECLARE
Déclaration de variables, constantes,
exceptions, curseurs]

BEGIN
Instructions SQL et PL/SQL
[EXCEPTION
Traitement des exceptions
(gestion des erreurs)]
END;
10 Prof: Andy PIERRE, M.Sc
2. Structure d’un bloc PL/SQL
Remarques :
-les sections DECLARE et EXCEPTION sont facultatives.

-chaque instruction se termine par un ;

-Les commentaires :
-- : sur une ligne
/* */ : sur plusieurs lignes
Pour exécuter un bloc anonyme dans le buffer de SQL*Plus, il faut utiliser le caractère slash
"/". Si le bloc s'exécute avec succès, sans erreurs soulevées ni d'erreurs de compilation, le
message suivant s'affiche :
« PL/SQL procedure successfully completed »

11 Prof: Andy PIERRE, M.Sc


2. Structure d’un bloc PL/SQL
Exemple :
DECLARE
v_ename VARCHAR2(5);
BEGIN
SELECT ename INTO v_ename FROM emp
WHERE empno = 1234;
EXCEPTION
WHEN NO_DATA_FOUND THEN

END;

La section déclarative de ce bloc déclare une variable de type


VARCHAR2, d'une longueur de 5 et appelée v_ename.

12 Prof: Andy PIERRE, M.Sc


Le langage PL/SQL
1. Introduction
2. Structure d’un bloc PL/SQL
3. Variables et Types de Données en PL/SQL
4. Traitement des données en PL/SQL
5. Procédures et fonctions en PL/SQL
6. Les curseurs en PL/SQL
7. Les Packages en PL/SQL
8. Utilisation des Triggers en ORACLE
9. Gestion des erreurs en PL/SQL

13 Prof: Andy PIERRE, M.Sc


3. Variables et Types de Données
3.1. Utilisation et traitement des variables
Une variable est un espace de stockage temporaire de données.
Syntaxe :
variable_name [CONSTANT] datatype [ := | DEFAULT expr] ;

Les variables locales se déclarent dans la partie DECLARE du bloc PL/SQL


ou après le mot réservé IS / AS dans une procédure ou Fonction.
Différents types de variables :

* Variables de types ORACLE

* Variables de type BOOLEAN

* Variables faisant référence au dictionnaire de données

14 Prof: Andy PIERRE, M.Sc


3. Les variables utilisées en PL/SQL
3.1. Utilisation et traitement des variables
• Initialisation des variables
• Visibilité des variables
3.1.1. Variables de type ORACLE
Syntaxe :
nom_variable TYPE_ORACLE;
Exemple :
DECLARE
nom CHAR(20);
prenom CHAR(15);
age NUMBER(3);
BEGIN

END;

15 Prof: Andy PIERRE, M.Sc


3. Les variables utilisées en PL/SQL
3.1.2. Variables de type BOOLEAN

Syntaxe :
nom_var BOOLEAN;

Exemple :
DECLARE
retour BOOLEAN;
BEGIN

END;

16 Prof: Andy PIERRE, M.Sc


3. Les variables utilisées en PL/SQL
3.1.3. Variables faisant référence au dictionnaire de données
* Variable de même type qu'un attribut d'une table de la base

Syntaxe :
nom_var table.colonne%TYPE;

Exemple :
DECLARE
nom pilote.plnom%TYPE;
BEGIN

END;

17 Prof: Andy PIERRE, M.Sc


3. Les variables utilisées en PL/SQL
3.1.3. Variables faisant référence au dictionnaire de données (suite ...

- Variable de même structure qu'une ligne d'une table de la base

Syntaxe :
nom_var table%ROWTYPE;
Exemple :
DECLARE
V_Pilote pilote%ROWTYPE;
BEGIN

END;

18 Prof: Andy PIERRE, M.Sc


3. Les variables utilisées en PL/SQL
3.1.3. Variables faisant référence au dictionnaire de données (suite ...
Remarque :
La structure ligne contient autant de variables que de colonnes de
la table. Ces variables portent le même nom et sont de même type
que les colonnes de la table.
Pour y accéder : <Nom_Variable>.<Nom Colonne>
Exemple :
V_Pilote.Pl#
V_Pilote.Plnom

V_Pilote.Sal

19 Prof: Andy PIERRE, M.Sc


3. Les variables utilisées en PL/SQL
3.1.3. Variables faisant référence au dictionnaire de données (suite ...
- Variable de même type qu'une autre variable

Syntaxe :
nom_var2 nom_var1%TYPE;
Exemple :

DECLARE
ancien_sal NUMBER(5);
nouveau_sal ancien_sal%TYPE; --NUMBER(5);
BEGIN

END;
20 Prof: Andy PIERRE, M.Sc
3.Variables et Types de Données
Remarque
Deux avantages à utiliser la forme de déclaration faisant référence
au dictionnaire de données:
1. Ce n’est pas nécessaire de connaître le type de données de la
colonne en question
2. Si le type de données (de la colonne de la table) change ce n’est
plus nécessaire d’apporter les nouvelles modifications au niveau
des codes.

21 Prof: Andy PIERRE, M.Sc


3. Les variables utilisées en PL/SQL
3.1.4. Initialisation des variables
opérateur :=
ou
SELECT ... INTO ...
Exemple I : Exemple II :
DECLARE DECLARE
var1 CHAR(10) := 'DUPONT'; v_n1 NUMBER := 500;
var2 NUMBER(5,2) := 100; v_n2 NUMBER := 1003;
var3 CHAR(10); v_value BOOLEAN;
var4 DATE; v_valid BOOLEAN;
BEGIN BEGIN
SELECT col1, col2 v_value := (v_n1 = v_n2);
INTO var3, var4 FROM ... ; v_valid := (v_value IS NOT NULL);
END;
END;

22 Prof: Andy PIERRE, M.Sc


3. Les variables utilisées en PL/SQL
3.1.4. Initialisation des variables
Remarque :
le SELECT doit ramener une et une seule ligne, sinon erreur, il faut
utiliser de préférence les curseurs

23 Prof: Andy PIERRE, M.Sc


3.1.5. Visibilité des variables
Une variable est visible dans le bloc où elle a été déclarée et dans
les blocs imbriqués si elle n'a pas été redéfinie.

DECLARE
variable1_v NUMBER(3) := 10 ;
BEGIN
variable1_v (10)

DECLARE
variable1_v NUMBER(3) := 200 ;
BEGIN
variable1_v (200)

END;
variable1_v (10)

END;

24
24 Prof: Andy PIERRE, M.Sc
3.Variables et Types de données
3.2. Variables de l'environnement extérieur à PL/SQL

Outre les variables locales vues précédemment, un bloc


PL/SQL peut utiliser d'autres variables :

- les variables définies en langage hôte (préfixée de :)

- les variables définies dans SQL*Plus (préfixée de &)

- les champs d'écrans FORMS

25 Prof: Andy PIERRE, M.Sc


3.Variables et Types de données
3.2. Variables de l'environnement extérieur à PL/SQL
3.2.1 les variables définies en langage hôte (préfixée de :)
Une variable hôte est une variable déclarée dans l'environnement
hôte utilisée pour passer des valeurs, en entrée ou en sortie d'un ou plusieurs
programmes PL/SQL. Des ordres PL/SQL peuvent référencer des variables
déclarées dans l'environnement hôte sauf si ces ordres se trouvent dans une
procédure, une fonction ou un package.

Déclarer une variable hôte :


VAR[IABLE] variable_name data_type
La longueur de la variable devra être précisé pour les types de chaîne de
caractères.

Exemple :
SQL> VARIABLE return_code NUMBER
SQL> VARIABLE return_msg VARCHAR2(30)

26 Prof: Andy PIERRE, M.Sc


3.Variables et Types de données
3.2. Variables de l'environnement extérieur à PL/SQL
3.2.1 les variables définies en langage hôte (préfixée de :)
Le SQL et l'environnement SQL*Plus peuvent référencer les variables
hôtes.
Pour afficher, sous SQL*Plus, toutes les variables hôtes définies et leurs types
de données ou le type de données d'une variable hôte donnée:
VAR[IABLE] {variable_name}
Pour afficher, sous SQL*Plus, la valeur courante de toutes les variables hôtes ou
d'une variable hôte donnée :
PRI[NT] {variable_name}
Pour faire référence à des variables hôtes ou des variables de substitution, vous
devez faire précéder les variables hôtes de deux points (:) et les variables de
substitution d'un ampersand afin de les distinguer des variables PL/SQL
déclarées.
:host_variable := expression
&substitution_variable := expression
Pour les chaînes de caractères :
'&substitution_variable' := expression

27 Prof: Andy PIERRE, M.Sc


3.Variables et Types de données
3.2. Variables de l'environnement extérieur à PL/SQL
3.2.1 les variables définies en langage hôte (préfixée de :)
Exemple :

VARIABLE g_monthly_sal NUMBER


ACCEPT p_annual_sal PROMPT ‘Entrer le salaire Annuel : '
DECLARE
v_sal NUMBER(9,2) := &p_annual_sal;
BEGIN
:g_monthly_sal := v_sal/12;
END;
/
PRINT g_monthly_sal

g_monthly_sal est une variable hôte référencée avec (:).


p_annual_sal est une variable de substitution référencée par (&).
A l'exécution du bloc, le moteur PL/SQL demandera la saisie de la variable
p_annual_sal. Sa valeur sera divisée par 12, le résultat sera stocké dans la variable
g_monthly_sal.

28 Prof: Andy PIERRE, M.Sc


Le langage PL/SQL
1. Introduction
2. Structure d’un bloc PL/SQL
3. Variables et Types de Données en PL/SQL
4. Traitement des données en PL/SQL
5. Procédures et fonctions en PL/SQL
6. Les curseurs en PL/SQL
7. Les Packages en PL/SQL
8. Utilisation des Triggers en ORACLE
9. Gestion des erreurs en PL/SQL

29 Prof: Andy PIERRE, M.Sc


4.Traitements des données en PL/SQL
4.1 Traitement conditionnel : if
4.2 Traitement répétitif: boucle de base LOOP
4.3 Traitement répétitif: boucle FOR
4.4 Traitement répétitif: boucle WHILE

30 Prof: Andy PIERRE, M.Sc


4.Traitements des données en PL/SQL
4.1 Traitement conditionnel : if
Execution d’un traitement en fonction d’une condition

IF condition1 THEN traitement1;

ELSIF condition2 THEN traitement2;

[ELSE traitement3;]

END IF;

31 Prof: Andy PIERRE, M.Sc


4.Traitements des données en PL/SQL
4.1 Traitement conditionnel : if
•Les operateurs utilisés sont les mêmes que dans SQL:
=, <,…., IS NULL, IS NOT NULL, LIKE,….

•Dès que l’une des conditions est vraie, le traitement qui suit le
THEN est exécuté.

•Si aucune condition n’est vraie, c’est le traitement qui suit le


ELSE qui est exécuté.

32 Prof: Andy PIERRE, M.Sc


4.Traitements des données en PL/SQL
EXEMPLE :

DECLARE
bonus NUMBER(6,2);
empid NUMBER(6) := 7369;
V_hiredate DATE;
BEGIN
SELECT hiredate INTO V_hiredate FROM emp WHERE empno = empid;
IF V_hiredate > TO_DATE('01-JAN-98') THEN
bonus := 500;
ELSIF V_hiredate > TO_DATE('01-JAN-96') THEN
bonus := 1000;
ELSE
bonus := 1500;
END IF;
DBMS_OUTPUT.PUT_LINE(‘Le Bonus employe No: ' || empid || ' is: ' || bonus );
END;
/
33 Prof: Andy PIERRE, M.Sc
4.Traitements des données en PL/SQL
4.2 Traitement répétitif: boucle de base LOOP
Exécution d’un traitement plusieurs fois, le nombre n’étant pas
Connu mais dépendant d’une condition.
BEGIN
LOOP [label]
instructions;
EXIT [label] WHEN condition
END LOOP [label] ;
END;
EXIT [label] WHEN condition permet de sortir de la boucle.

34 Prof: Andy PIERRE, M.Sc


4.Traitements des données en PL/SQL
4.2 Traitement répétitif: boucle de base LOOP
Exemple: insérer les 10 premiers chiffres dans une table
Solution
DECLARE
nb NUMBER:=1;
BEGIN
LOOP
insert into solution values(nb);
nb:=nb+1;
EXIT WHEN nb>10
END LOOP;
Commit;
END;06/2009
35 Prof: Andy PIERRE, M.Sc
4.Traitements des données en PL/SQL
4.3 Traitement répétitif: boucle FOR
Exécution d’un traitement plusieurs fois, le nombre étant connu
BEGIN
FOR indice IN [REVERSE] exp1..exp2
LOOP
instructions;
END LOOP;
END;

Remarques
•Inutil de déclarer indice
•Indice varie de exp1 à exp2 (pas=1)
•Si REVERSE, indice varie de exp2 à exp1 (pas=-1)

36 Prof: Andy PIERRE, M.Sc


4.Traitements des données en PL/SQL
4.2 Traitement répétitif: boucle FOR (suite)
Exemple: calcul de la factorielle de 10
DECLARE
factoriel NUMBER:=1;
BEGIN
DELETE FROM Solution;
FOR i IN 1..10
LOOP
factoriel :=factoriel*i;
Insert Into solution Values(factoriel);
END LOOP;
Commit;
END;
37 Prof: Andy PIERRE, M.Sc
4.Traitements des données en PL/SQL
4.4 Traitement répétitif: boucle WHILE
Exécution d’un traitement tant qu’une condition reste vraie
BEGIN
WHILE condition
LOOP
instructions;
END LOOP;
END;

38 Prof: Andy PIERRE, M.Sc


4.Traitements des données en PL/SQL
4.2 Traitement répétitif: boucle WHILE
Exemple: reste de la division de 9856 par 7
DECLARE
reste NUMBER:=9856;
BEGIN
DELETE FROM Solution;
WHILE reste>=7
LOOP
reste:=reste-7;
END LOOP;
INSERT INTO Solution VALUES(reste);
Commit;
END;
39 Prof: Andy PIERRE, M.Sc
Le langage PL/SQL
1. Introduction
2. Structure d’un bloc PL/SQL
3. Variables et Types de Données en PL/SQL
4. Traitement des données en PL/SQL
5. Procédures et fonctions en PL/SQL
6. Les curseurs en PL/SQL
7. Les Packages en PL/SQL
8. Utilisation des Triggers en ORACLE
9. Gestion des erreurs en PL/SQL

40 Prof: Andy PIERRE, M.Sc


5. Procédures et fonctions
5.1 Problématique
5.2 Code Modulaire
5.3 Bloc PL/SQL anonyme
5.4 Procédures
5.5 Fonctions
5.6 Parameters
5.7 Modules locaux
5.8 Surcharge de modules

41 Prof: Andy PIERRE, M.Sc


5. Procédures et fonctions
5.1 Problématique
1. Peu de taches sont évidentes

1. Peu de solutions peuvent être conçues en un clin


d’œil et mises en oeuvre immédiatement

3. Le systèmes à construire sont vastes et complexes

42 Prof: Andy PIERRE, M.Sc


5. Procédures et fonctions
5.1 Problématique
Les enjeux:
1. L’esprit humain peut résoudre 7 +/- 2 taches à la fois
2. Trouver le moyen de réduire la complexité de
l’environnement
3. Ramener d’énormes et impressionnants projets à des
composants de taille plus gérables

43 Prof: Andy PIERRE, M.Sc


5. Procédures et fonctions
5.2 Code Modulaire
Modularisation=décomposition de gros blocs de codes en plus
petits éléments(modules) qui peuvent être appelés par d’autres
modules
Avantages de la modularisation:
codes
•Réutilisables
•Gérables
•Lisibles
•Fiables

44 Prof: Andy PIERRE, M.Sc


5. Procédures et fonctions
5.2 Code Modulaire
PL/SQL fournit les structures suivantes permettant de
modulariser le code de différentes façons:
• Block anonyme
• Procédures
• Fonctions
• Packages
• Triggers de Base de Données
Procédure
Bloc PLS/SQL nommé qui exécute une ou plusieurs actions et est
appelé comme une commande PL/SQL. La récupération des
informations d’une procédure se fait à travers sa liste de paramètre

45 Prof: Andy PIERRE, M.Sc


5. Procédures et fonctions
Format général d’une Procédure PL/SQL
[CREATE OR REPLACE] PROCEDURE nom_procedure
[(parametre [,parametre2]..)]

IS|AS

[DECLARATION]

BEGIN
instructions_executables

[traitement des EXCEPTIONS]

END nom_procedure ;

46 Prof: Andy PIERRE, M.Sc


5. Procédures et fonctions
Format général d’une Procédure PL/SQL
[CREATE OR REPLACE]: optionnel si l’on utilise un outil tel que Oracle forms
(developer 2000), obligation en SQL*Plus

nom_procedure: nom de procedure

[(paramètre [,parametre2]..)] : paramètres optionnels de la procedure

[DECLARATION]: déclaration des variables locales utiles à la procedure.

instructions_executables: instruction à exécuter par la procedure lorsqu’elle sera


appelée

[traitement des EXCEPTIONS]

47 Prof: Andy PIERRE, M.Sc


Exemple de procedure
CREATE OR REPLACE PROCEDURE CALCUL_bonus (emp_id NUMBER) IS
bonus REAL;
comm_missing EXCEPTION;
BEGIN
SELECT comm INTO bonus FROM emp WHERE empno = emp_id;
IF bonus IS NULL THEN
UPDATE EMP SET COMM = SAL*.1 WHERE empno = emp_id;
ELSE
UPDATE EMP SET COMM = COMM*1.1 WHERE empno = emp_id;
END IF;
EXCEPTION
WHEN comm_missing THEN NULL;
END;
/

48 Prof: Andy PIERRE, M.Sc


Manipulation d’une procedure
Compilez la procédure calcul_bonus en suivant les instructions ci-dessous
1. Création d’un fichier “calcul_bonus.sql”

2. Lancement du fichier sql: SQL> @chemin:\calcul_bonus.sql


ou SQL>sta @chemin:\calcul_bonus.sql

3. Correction éventuelle des erreurs de la procédure (si le message suivant est affiché)
Warning: Procedure created with compilation errors.
SQL> show errors|show err|show error), puis apportez les correctifs nécessaires

4. Exécution de la procédure
EXECUTE calcul_bonus(numéro d’un employé)
5. Vérifier que la procédure a exécuté les instructions demandées
(interrogation de la table emp)

49 Prof: Andy PIERRE, M.Sc


5. Procédures et fonctions
Appel d’une Procédure PL/SQL
Une procédure est appelée comme une instruction PL/SQL
Exécutable : nom_procedure(liste_paramètres);
ou nom_procedure;

Exemple: CALCUL_bonus (9878) ;

50 Prof: Andy PIERRE, M.Sc


Exercices PL/SQL
1. Les boucles
Créer une table MULTIPLICATION(Num Number(2),Seq Number(2), Result Number(5))
Écrire un fichier de commande permettant le calcul et l’affichage d’une table de multiplication
.
Résoudre le problème de trois manières différentes(utiliser les trois boucles)

51 Prof: Andy PIERRE, M.Sc


5. Procédures et fonctions
5.2 Code Modulaire(suite)
Fonction
• Présentation
• Structure générale d’une fonction PL/SQL
• Type de données renvoyé
• Mode d’utilisation des paramètres
• Valeur par défaut
• Surcharge des procédures et fonctions

52 Prof: Andy PIERRE, M.Sc


5. Procédures et fonctions
5.2 Code Modulaire(suite)
Fonction
Bloc PLS/SQL nommé qui renvoie une seule valeur comme une
expression PL/SQL. Des informations peuvent être passées à
une fonction à travers sa liste de paramètres

Structure d’une fonction


La structure d’une fonction est la même que celle d’une procédure
Sauf qu’une fonction comporte une clause RETURN

53 Prof: Andy PIERRE, M.Sc


5. Procédures et fonctions
Structure générale d’une fonction PL/SQL
[CREATE OR REPLACE] FUNCTION nom_fonction
[(parametre [,parametre2]..)] RETURN type_de_données

IS|AS

[DECLARATION]

BEGIN
instructions_executables

[traitement des EXCEPTIONS]

END [nom_fonction] ;

54 Prof: Andy PIERRE, M.Sc


5. Procédures et fonctions
Structure générale d’une fonction PL/SQL (suite)
nom_fonction : nom de fonction

Paramètres : Liste optionnelle de paramètres définis pour passer de


l’information à la fonction et/ou pour en récupérer, à
partir du programme appelant.

type_de_données : type de données renvoyé. Obligatoire


dans l’en-tête de la fonction

55 Prof: Andy PIERRE, M.Sc


5. Procédures et fonctions
Structure générale d’une fonction PL/SQL (suite)

Type de données renvoyé


Ce type peut être n’importe quel type de données autorisé par le
PL/SQL, notamment :
VARCHAR2
NUMBER
BINARY_INTEGER (nombres signés, -2^31+1 à 2^31 -1 )
BOOLEAN
Table_PL/SQL
Enregistrement PL/SQL
DATE
REAL

56 Prof: Andy PIERRE, M.Sc


5. Procédures et fonctions
Exemple de fonction PL/SQL
CREATE OR REPLACE FUNCTION sal_ok (salary REAL, title
VARCHAR2) RETURN BOOLEAN IS
min_sal REAL;
max_sal REAL;

BEGIN
SELECT losal, hisal INTO min_sal, max_sal FROM sals
WHERE job = title;
RETURN (salary >= min_sal) AND (salary <= max_sal);
END ;

Appel de la fonction : IF sal_ok(new_sal, new_title) THEN ...

57 Prof: Andy PIERRE, M.Sc


5. Procédures et fonctions
Limites des fonctions PL/SQL
Une fonction PL/SQL ne peut modifier ni les objets ni les données
d’une base de données
Mode d’utilisation des paramètres
IN : lecture seule, le paramètre ne peut être modifié

OUT : écriture seule, peut être modifié, mais ne peut être


référencé

IN OUT : Lecture/écriture: peut être à fois modifié et


référencé

58 Prof: Andy PIERRE, M.Sc


5. Procédures et fonctions
Exemple
CREATE OR REPLACE PROCEDURE query_emp (v_id IN emp.empno%TYPE,
v_name OUT emp.ename%TYPE, v_salary OUT emp.sal%TYPE,
v_comm OUT emp.comm%TYPE) IS
BEGIN
SELECT ename, sal, comm INTO v_name, v_salary, v_comm FROM emp
WHERE empno = v_id;
END query_emp;
/

Valeurs par défaut


Appel de programme en utilisant un nombre différent de
Paramètres. Le programme utilise la valeur par défaut pour
tout Paramètre non spécifié

59 Prof: Andy PIERRE, M.Sc


5. Procédures et fonctions
Valeurs par défaut(suite)
CREATE OR REPLACE PROCEDURE add_dept
(v_name IN dept.dname%TYPE DEFAULT ’unknown’,
v_loc IN dept.loc%TYPE DEFAULT ’unknown’) IS
BEGIN
INSERT INTO dept VALUES (Seq_dept.NEXTVAL, v_name, v_loc);
END add_dept;
Appel de la procédure
BEGIN
add_dept;
add_dept ( ’TRAINING’, ’NEW YORK’);
add_dept ( v_loc => ’DALLAS’, v_name =>’EDUCATION’);
add_dept ( v_loc => ’BOSTON’) ;
END; ;

60 Prof: Andy PIERRE, M.Sc


5. Procédures et fonctions
Surcharge de procédures et de fonctions
Deux ou plusieurs procédures portant le même nom et une
liste différente de paramètres. Le code de ces programmes
peut être semblable ou complètement différent.
Exemple:
CREATE FUNCTION valeur_ok(date_in IN DATE) RETURN
BOOLEAN IS
BEGIN
RETURN date_in<=SYSDATE;
END;
61 Prof: Andy PIERRE, M.Sc
5. Procédures et fonctions
Surcharge de procédures et de fonctions(suite)
Exemple:
CREATE FUNCTION valeur_ok(nombre_in IN NUMBER) RETURN BOOLEAN IS
BEGIN
RETURN nombre_in>0;
END;
Appel de la Fonction
Valeur_ok(SYSDATE); valeur_ok(200);
Exemple de surcharge dans les standards PL/SQL
Chaine_date :=TO_CHAR(SYSDATE,’DD-MM-YYYY’);
Chaine_nombre := TO_CHAR(1000);

62 Prof: Andy PIERRE, M.Sc


5. Procédures et fonctions
5.2 Code Modulaire(suite)
Block anonyme
Bloc PLS/SQL non nommé qui exécute une ou plusieurs actions.
Un block anonyme permet au développeur de contrôler la portée
Des identifiants et la gestion des exceptions.

Package
Ensemble nommé de fonctions, procedures, types et variables.
Un package c’est un meta-module

63 Prof: Andy PIERRE, M.Sc


Le langage PL/SQL
1. Introduction
2. Structure d’un bloc PL/SQL
3. Variables et Types de Données en PL/SQL
4. Traitement des données en PL/SQL
5. Procédures et fonctions en PL/SQL
6. Les curseurs en PL/SQL
7. Les Packages en PL/SQL
8. Utilisation des Triggers en ORACLE
9. Gestion des erreurs en PL/SQL

64 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL
6.1 Définitions
6.2 Curseur explicite
6.3 Attributs d’un curseur
6.4 Simplification d’écriture

65 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL
6.1. Introduction sur les curseurs

Les curseurs permettent de nommer des zones de mémoire SQL privée et d’accéder
ainsi aux informations qui y sont stockées lors de l’exécution d’une instruction SQL.
Il existe deux types de curseurs :
les curseurs implicites (ou curseurs SQL) et explicites.
Les curseurs implicites et explicites réalisent la même fonction, à savoir la fourniture
d’espace mémoire pour le traitement des lignes. La différence entre eux réside dans la
façon dont ils sont déclarés :
-Un curseur implicite est automatiquement (implicitement) déclaré par PL/SQL lors de
l'exécution d'instructions PL/SQL et DML (telles que INSERT, UPDATE et DELETE).
-Un curseur explicite est déclaré et nommé par le programmeur. Les curseurs
explicites sont manipulés grâce à des instructions spécifiques dans la section exécutable
d'un bloc.
L’avantage de la création d’un curseur explicite est de pouvoir l’utiliser pour traiter
plusieurs ensembles de résultats de lignes. Le traitement dans un curseur explicite se fait
ligne par ligne au-delà de la première ligne renvoyée par la requête.

66 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL
6.1. Introduction sur les curseurs
6.1.1. Curseur SQL ou Implicites
Lorsqu’une commande SQL est exécuté, le serveur Oracle réserve une zone de la
mémoire pour l ‘analyse et l’exécution de cette commande. Cette zone est appelé
curseur SQL ou curseur implicite.
Un curseur SQL ne peut pas être ouvert ou fermé par un programme. PL/SQL
traite implicitement le curseur et le ferme, mais ne gère pas l’ouverture du curseur.
Attributs des curseurs SQL
Les résultats d’un curseur SQL peuvent être évalués à l’aide d’attributs de curseurs
SQL. Il existe quatre attributs des curseurs SQL :
SQL%ROWCOUNT Nombre de lignes affectées par la dernière instruction SQL.

SQL%FOUND Retourne TRUE si la dernière instruction SQL a retourné une ou plusieurs lignes.

SQL%NOTFOUND Retourne TRUE si la dernière instruction SQL n’a retourné aucune ligne.

SQL%ISOPEN Détermine si un curseur est ouvert. Il prend toujours la valeur FALSE, car PL/SQL ferme les
curseurs implicites immédiatement après leur exécution.

67 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL
6.1. Introduction sur les curseurs
6.1.1. Curseur SQL ou Implicites

Les attributs des curseurs SQL ne peuvent pas être utilisés dans des ordres SQL; mais
ils peuvent être utilisés dans la section de traitement des exceptions d'un bloc PL/SQL.
Exemple :

PROMPT Numero Employe:


ACCEPT Num
VARIABLE rows_deleted VARCHAR2(30)
DECLARE
v_Empid NUMBER :=&Num;
BEGIN
DELETE FROM Emp WHERE Empno = v_Empid;
: rows_deleted := (SQL%ROWCOUNT || ' lignes suprimees.');
END;
/
PRINT rows_deleted

68 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL

6.1.2. Les caractéristiques des curseurs explicites


Les curseurs explicites sont déclarés par l’utilisateur et sont utilisés pour traiter les
résultats d’une requête qui retournent plusieurs lignes.

L'instruction SELECT..INTO ne doit retourner qu'une seule ligne. Un curseur explicite


permet de gérer des requêtes retournant plusieurs lignes et de traiter chaque ligne
individuellement.

Les lignes renvoyées par une requête sont appelées ensemble actif. PL/SQL définit
automatiquement la taille du curseur en fonction de la taille de l’ensemble actif.

Un curseur explicite possède un pointeur inhérent qui enregistre la ligne courante


(actuellement en cours de traitement) de l’ensemble actif.

Les curseurs explicites peuvent être contrôlés manuellement par le programmeur.

69 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL
6.1.3. Contrôle des curseurs explicites
Le contrôle d’un curseur est le processus de création et d’utilisation d’un curseur.
Le contrôle des curseurs a lieu en quatre étapes :
1.-Déclaration du curseur :
Un curseur explicite est déclaré en le nommant et en définissant la structure de la requête
dont il stockera le résultat.
2.- Ouverture du curseur :
L’instruction OPEN est utilisée pour ouvrir un curseur explicite. L’instruction exécute la
requête et identifie l’ensemble actif (résultat de la requête).
3.- Accès aux données du curseur :
Une fois un curseur explicite déclaré et ouvert, le résultat de la requête du curseur peut
être accédé. L’instruction FETCH est utilisée pour extraire une ligne à la fois de l’ensemble
actif. Elle charge la ligne actuelle du curseur dans les variables. Pour accéder à une ligne
à la fois, l’extraction doit être effectuée à l'intérieure d'une boucle.

70 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL
6.1.3. Contrôle des curseurs explicites
4.-Fermeture du curseur :
L’instruction CLOSE permet de fermer un curseur explicite. L’instruction CLOSE libère
l’ensemble actif du curseur.

71 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL
6.2. Utilisation des curseurs explicites
6.2.1. Déclaration des curseurs explicites
Un curseur est déclaré dans la section déclarative à l’aide de l’instruction CURSOR.
CURSOR cursor_name IS Select_statement ;

Un curseur doit être déclaré, nommé et associé à une requête. La requête peut contenir
des variables préalablement déclarées, mais en aucun cas de clause INTO.
Exemple :

DECLARE
CURSOR emp_cursor IS SELECT empno, sal * 10 FROM emp;
BEGIN

END ;

72 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL

6.2. Utilisation des curseurs explicites


6.2.2. Ouverture des curseurs explicites
L’ouverture d’un curseur exécute la requête associée au curseur et identifie l'ensemble
actif.
OPEN cursor_name ;
L’instruction OPEN :
-Alloue de façon dynamique de la mémoire pour une zone de contexte destinée à
contenir les informations de traitement.
-Parse la requête associée au curseur.
- "binds" les variables en entrée.
-Identifie l'ensemble actif.
-Positionne le pointeur juste avant la première ligne du curseur.

Si le curseur est déclaré avec la clause FOR UPDATE, l'ordre OPEN verrouille les lignes
retournées par la requête.

73 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL
6.2. Utilisation des curseurs explicites
6.2.3. Extraction de données d’un curseur explicite
L’instruction FETCH est utilisée pour extraire une par une les lignes de l'ensemble actif.
FETCH cursor_name INTO {variable1 [,variable2…] | record_name} :
La clause INTO contient les noms des variables ou le nom d'un enregistrement PL/SQL
dans lequel les données de l'ensemble actif seront stockées pour permettre le traitement.
L’instruction FETCH :
- Avance le pointeur à la prochaine ligne de l'ensemble actif.
- Lit les données de la ligne courante de l'ensemble actif.
- Extrait les valeurs de la ligne actuelle et les places dans les variables de la clause INTO.
Le nombre de variables à déclarer dépend du nombre de champs retournés par l'ordre
FETCH. La clause INTO de l’instruction FETCH autant de variables qu'il y a de colonnes
dans la clause SELECT de la requête associée au curseur.
Pour chaque valeur de colonne retournée par la requête associée au curseur, il doit y
avoir une variable qui lui correspond dans la clause INTO. Les types de données des
variables doivent être compatibles aux types de données des colonnes qui leur
correspondent.
Le pointeur du curseur avance jusqu’à la ligne suivante à chaque exécution de la
commande FETCH.

74 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL
6.2. Utilisation des curseurs explicites
6.2.3. Extraction de données d’un curseur explicite

Exemple :
DECLARE
v_empno emp.empno%TYPE;
v_ename emp.ename%TYPE;
CURSOR emp_cursor IS
SELECT empno, ename FROM emp;
BEGIN
OPEN emp_cursor;
FOR i IN 1..10
LOOP
FETCH emp_cursor INTO v_empno, v_ename;

END LOOP;

END ;

75 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL
6.2. Utilisation des curseurs explicites
6.2.4. Fermeture d’un curseur
L'instruction CLOSE est utilisée pour fermer le curseur.
CLOSE cursor_name ;
L'instruction CLOSE :

- désactive le curseur (l'ensemble actif devient indéfini).

- libère des ressources pouvant être utilisées pour l’extraction d’autres tâches.

Bien qu’il soit possible de terminer le bloc PL/SQL sans fermer le curseur, il est
préférable de le fermer explicitement. De plus, le nombre de curseurs ouverts pour
chaque utilisateur est limité par le paramètre de base de données OPEN_CURSORS qui
vaut, par défaut, 50.
L’accès aux données n’est plus possible après la fermeture d’un curseur.

Si une tentative d’accès aux données à partir d’un curseur fermé est effectuée, une
exception INVALID_CURSOR est levée.

76 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL
6.3. Les attributs des curseurs explicites

Comme dans le cas des curseurs implicites, quatre attributs permettent d’obtenir les
informations relatives à l’état d’un curseur explicite : %ISOPEN, %FOUND,
%NOTFOUND et%ROWCOUNT.
Ces attributs ne peuvent pas être utilisés dans des ordres SQL.

6.3.1. Contrôle de l’état à l’aide de l’attribut %ISOPEN

L’attribut %ISOPEN est un attribut booléen qui prend la valeur TRUE si le curseur est
ouvert. Si FALSE est le résultat de l’attribut %ISOPEN, le curseur peut être ouvert.
L’ajout du mot clé NOT inverse la condition.

cursor_name%ISOPEN
NOT cursor_name%ISOPEN

77 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL
6.3. Les attributs des curseurs explicites
6.3.1. Contrôle de l’état à l’aide de l’attribut %ISOPEN
Exemple :
BEGIN

IF NOT emp_cursor%ISOPEN THEN


OPEN emp_cursor ;
END IF ;
LOOP
FETCH emp_cursor ...
END LOOP;
CLOSE emp_cursor ;

END ;
7
78 Prof: Andy PIERRE, M.Sc
6. Les curseurs en PL/SQL
6.3. Les attributs des curseurs explicites
6.3.1. Contrôle de l’état à l’aide de l’attribut %ISOPEN
Exemple :
BEGIN

IF NOT emp_cursor%ISOPEN THEN


OPEN emp_cursor ;
END IF ;
LOOP
FETCH emp_cursor ...
END LOOP;
CLOSE item_cursor ;

END ;

79 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL
6.3. Les attributs des curseurs explicites
6.3.2. Contrôle de l’état à l’aide de l’attribut %FOUND
%FOUND est un attribut de type booléen qui prend la valeur TRUE si
l’opération d’accès la plus récente a renvoyé une ligne. Lorsque aucune ligne
n’est renvoyée, l’attribut prend la valeur FALSE.
cursor_name%FOUND
Exemple :

BEGIN
OPEN emp_cursor ;
FETCH emp_cursor INTO v_empno, v_ename ;
WHILE emp_cursor%FOUND
LOOP
INSERT INTO emp2 VALUES (v_empno, v_ename) ;
FETCH emp_cursor INTO v_empno, v_ename ;
END LOOP ;
END ;
80 Prof: Andy PIERRE, M.Sc
6. Les curseurs en PL/SQL
6.3. Les attributs des curseurs explicites
6.3.3. Sortie d’une boucle à l’aide de l’attribut %NOTFOUND
%NOTFOUND est un attribut booléen qui prend la valeur TRUE si l’opération
d’accès la plus récente ne renvoie aucune ligne. Si une ligne est renvoyée,
l’attribut prend la valeur FALSE.
cursor_name%NOTFOUND
Avant le premier ordre FETCH, l'attribut %NOTFOUND est évalué à NULL.
Exemple :

BEGIN
OPEN emp_cursor ;
LOOP
FETCH emp_cursor INTO v_empno, v_ename;
EXIT WHEN emp_cursor%NOTFOUND;
END LOOP ;
CLOSE emp_cursor;
END ;

81 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL
6.3. Les attributs des curseurs explicites
6.3.4. Nombre de lignes renvoyées à l’aide de %ROWCOUNT
%ROWCOUNT est un attribut numérique qui prend la valeur du nombre total
de lignes accédées jusqu’alors dans une boucle.
cursor_name%ROWCOUNT
Exemple :

BEGIN
OPEN emp_cursor ;
LOOP
FETCH emp_cursor INTO v_empno, v_ename ;
EXIT WHEN emp_cursor%ROWCOUNT > 5 ;
END LOOP ;
END ;
La boucle LOOP et l'instruction FETCH permettent d'extraire les cinq
premières lignes de l'ensemble actif de emp_cursor.

82 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL
6.3. Les attributs des curseurs explicites
6.3.4. Nombre de lignes renvoyées à l’aide de %ROWCOUNT
%ROWCOUNT est un attribut numérique qui prend la valeur du nombre total
de lignes accédées jusqu’alors dans une boucle.
cursor_name%ROWCOUNT
Exemple :

BEGIN
OPEN emp_cursor ;
LOOP
FETCH emp_cursor INTO v_empno, v_ename ;
EXIT WHEN emp_cursor%ROWCOUNT > 5 ;
END LOOP ;
END ;
La boucle LOOP et l'instruction FETCH permettent d'extraire les cinq
premières lignes de l'ensemble actif de emp_cursor.

83 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL
6.4. Utilisation avancée des curseurs explicites
6.4.1 Utilisation d’un Structure
Au lieu de déclarer autant de variables que d ’attributs ramenés
par le SELECT du curseur, on peut utiliser une structure.
Syntaxe:
DECLARE
CURSOR nom_curseur IS ordre_select;
nom_structure nom_curseur%ROWTYPE;
Pour renseigner la structure:
FETCH nom_curseur INTO nom_structure;
Pour accéder aux éléments de la structure :
nom_structure.nom_colonne;

84 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL
6.4. Utilisation avancée des curseurs explicites
6.4.1 Utilisation d’un Structure

Exemple :
DECLARE
CURSOR emp_cursor IS
SELECT empno, ename FROM emp;
S_emp emp_cursor%ROWTYPE;
BEGIN
OPEN emp_cursor;
FOR i IN 1..10
LOOP
FETCH emp_cursor INTO S_emp;
DBMS_OUTPUT.PUT_LINE (‘Nom Employe No:’||S_Emp.empno || ‘est ‘
| | S_Emp.ename);
END LOOP;
CLOSE emp_cursor;
END ;

85 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL
6.4. Utilisation avancée des curseurs explicites
6.4.2. Extraction de lignes à l’aide de la boucle de curseur FOR

La boucle de curseur FOR permet d'extraire et de traiter une par une les lignes de
l'ensemble actif.
FOR record_name IN cursor_name
LOOP
statements ;
END LOOP ;
La boucle de curseur FOR ouvre et ferme automatiquement le curseur.
De plus, il n’est plus nécessaire de déclarer l'enregistrement PL/SQL contrôlant la
boucle (record_name) , celui-ci est déclaré implicitement par la boucle de curseur FOR

Une boucle de curseur FOR sélectionne une plage de lignes d’une table de base de
données, puis extrait chaque ligne de cette plage.

Les paramètres d’un curseur peuvent être spécifiés entre parenthèses après le nom du
curseur dans l’instruction FOR

86 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL
6.4. Utilisation avancée des curseurs explicites
6.4.2. Extraction de lignes à l’aide de la boucle de curseur FOR

Exemple :

SET SERVEROUT ON
DECLARE
CURSOR emp_cursor IS SELECT ename, deptno FROM emp ;
BEGIN
FOR emp_record IN emp_cursor
LOOP
IF emp_record.deptno = 30 THEN
DBMS_OUTPUT.PUT_LINE ('Employe '||
emp_record.ename || ' Travaille au departement de Ventes.');
END IF;
END LOOP ;
END ;

87 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL
6.4. Utilisation avancée des curseurs explicites
6.4.3. Déclaration de curseurs explicites avec des paramètres

Il est possible d’utiliser le même curseur dans différentes situations et d’extraire des
données différentes chaque fois. Pour cela, des paramètres sont passés au curseur
autorisant ainsi l’exécution de la requête pour différentes valeurs. Un curseur avec des
paramètres aboutit à des ensembles actifs différents suivant les paramètres passés au
curseur.
CURSOR cursor_name [(parameter [IN] datatype [{:= | DEFAULT} expr, …)]
IS select_statement ;
Le nom du paramètre doit être suivi d’un type de données scalaire. La taille des
données des paramètres ne doit pas être spécifiée. Les valeurs des paramètres sont
transmises au curseur lors de son ouverture. Ces valeurs sont utilisées dans la requête
du curseur lors de son exécution.
OPEN cursor_name (value,...)

ou

88 Prof: Andy PIERRE, M.Sc


6. Les curseurs en PL/SQL
6.4. Utilisation avancée des curseurs explicites
6.4.3. Déclaration de curseurs explicites avec des paramètres

FOR record_name IN cursor_name(value,...)


LOOP

END LOOP;

Exemple :
DECLARE
CURSOR emp_cursor ( p_job emp.job%TYPE, p_deptno emp.deptno%TYPE) IS
SELECT ename, empno, hiredate FROM emp
WHERE deptno= p_deptno AND job = p_job ;
BEGIN
OPEN emp_cursor('ANALYST',20);

END ;

89 Prof: Andy PIERRE, M.Sc


Exercices PL/SQL
2- Les curseurs

Écrire un fichier de commande permettant d’afficher les n plus anciens employés de l’entreprise
(recherche sur la date d’embauche)

90 Prof: Andy PIERRE, M.Sc


Le langage PL/SQL
1. Introduction
2. Structure d’un bloc PL/SQL
3. Variables et Types de Données en PL/SQL
4. Traitement des données en PL/SQL
5. Procédures et fonctions en PL/SQL
6. Les curseurs en PL/SQL
7. Les Packages en PL/SQL
8. Utilisation des Triggers en ORACLE
9. Gestion des erreurs en PL/SQL

91 Prof: Andy PIERRE, M.Sc


7. Les Packages en PL/SQL
7.1. Aperçu des packages
Les packages sont des groupes comprenant des types, des éléments et
des sous-programmes PL/SQL logiquement associés. Par exemple un package
Ressources Humaines pourrait contenir les procédures embauche et licenciement, les
fonctions commission et bonus et les variables d’exemption de taxe.
Généralement un package est constitué de deux parties stockées séparément dans la
base de données : la spécification et le corps.
La spécification est l’interface pour les applications. Elle déclare les types, les
variables, les constantes, les exceptions, les curseurs et les sous-programmes que l’on
peut utiliser dans le package.
Le corps définit les curseurs et les sous-programmes et ce qui a été défini dans la
spécification.
o Le package lui-même ne peut pas être appelé, recevoir de paramètre ou être
imbriqué. Une fois écrit et compilé, le contenu peut être partagé par plusieurs
applications.
o Quand on appelle un élément de package pour la première fois, tout le package est
chargé en mémoire. Par conséquent, les appels suivant à l’élément en question ne
requièrent pas d’écriture ou de lecture sur le disque.

92 Prof: Andy PIERRE, M.Sc


7. Les Packages en PL/SQL
7.2. Les composantes d’un packages

Sur le schéma on distingue les


zones de déclarations :
pour les variables publiques (1), les
procédures publiques (2),
les procédures privées (3),
les variables privées spécifiques au
package (4) et les variables locales
spécifiques à la procédure (5).

93 Prof: Andy PIERRE, M.Sc


7. Les Packages en PL/SQL
7.3. Référencer les objets d’un package
Les variables définies dans le package
n’ont pas toutes la même visibilité
c'est-à-dire que selon l’endroit où l’on
se trouve on ne pourra pas utiliser
certaines variables.
Variable locale : variable définie dans
un sous-programme du package.
Variable privée : variable définies dans le
corps du package.
Variable globale : variable définie dans la
spécification du package.

94 Prof: Andy PIERRE, M.Sc


7. Les Packages en PL/SQL
7.4. Creation d’un package
7.4.2. Création des spécifications du package
Pour créer la spécification d’un package on utilise la commande CREATE
[OR REPLACE] PACKAGE. Il faut spécifier toutes les structures publiques dans la
spécification du package.
Syntaxe :
CREATE [OR REPLACE] PACKAGE package_name
IS|AS
<Declarations des elements publiques ( Variables, Constantes …)
<Entete des Procedures et/ou Fonctions>
END package_name;

Exemple :

CREATE OR REPLACE PACKAGE comm_package IS


PROCEDURE reset_comm (v_comm IN NUMBER);
END comm_package;
/

95 Prof: Andy PIERRE, M.Sc


7. Les Packages en PL/SQL
7.4. Creation d’un package
7.4.3. Création du corps du package

Pour créer le corps du package on utilise la commande CREATE


PACKAGE BODY. Dans le corps du package on définit tous les éléments publics et
privés du package.
Syntaxe :

CREATE [OR REPLACE] PACKAGE BODY package_name


IS|AS
<Declarations Locales des Elements( Variables, Constantes …)
<Définition des sous-programmes PL/SQL publics et privés>
END package_name;

L’ordre dans lequel les sous-programmes sont définis est très important. Il
faut déclarer ou définir les sous-programmes privés avant de les appeler depuis
d’autres sous-programmes. Le plus souvent, toutes les variables et sous-
programmes privés sont déclarés en premier dans le corps du package et ensuite on
définit les sous-programmes publics.

96 Prof: Andy PIERRE, M.Sc


7. Les Packages en PL/SQL
7.4. Creation d’un package
7.4.3. Création du corps du package : EXEMPLE

CREATE OR REPLACE PACKAGE BODY comm_package


IS
FUNCTION validate_comm (v_comm IN NUMBER) RETURN BOOLEAN IS
v_max_comm NUMBER;
BEGIN
SELECT max(comm) INTO v_max_comm FROM emp;
IF v_comm > v_max_comm THEN RETURN(FALSE); ELSE RETURN(TRUE); END IF;
END validate_comm;
PROCEDURE reset_comm (v_comm IN NUMBER) IS
l_comm NUMBER := 10;
BEGIN
IF validate_comm(v_comm) THEN l_comm:=v_comm; ELSE
RAISE_APPLICATION_ERROR (-20210,’Invalid commission’);
END IF;
END reset_comm;
END comm_package;
/

97 Prof: Andy PIERRE, M.Sc


7. Les Packages en PL/SQL
7.5. Manipuler les packages
7.5.1.Exécuter une procédure publique d’un package
Une procédure publique est déclarée dans la spécification du package et
est définie dans le corps du package. Par conséquent, il est possible de l’appeler
directement depuis l’environnement SQL*Plus. Pour cela, on utilise la commande
EXECUTE en précisant le nom du package, de la procédure et les arguments, s’il y a
lieu d’en fournir.
Syntaxe :
SQL> EXECUTE package_name. procedure_name( parameters)
Exemple :
SQL> EXECUTE comm_package.reset_comm(15)
• Cet ordre SQL appelle la procédure RESET_COMM du package COMM_PACKAGE en
donnant un argument. Cet ordre peut être exécuté à n’importe quel moment
pendant la session de travail.
7.5.2 Supprimer un Package
Syntaxe : DROP PACKAGE BODY package_name
DROP PACKAGE package_name

98 Prof: Andy PIERRE, M.Sc


Le langage PL/SQL
1. Introduction
2. Structure d’un bloc PL/SQL
3. Variables et Types de Données en PL/SQL
4. Traitement des données en PL/SQL
5. Procédures et fonctions en PL/SQL
6. Les curseurs en PL/SQL
7. Les Packages en PL/SQL
8. Utilisation des Triggers en ORACLE
9. Gestion des erreurs en PL/SQL

99 Prof: Andy PIERRE, M.Sc


8. Création de triggers de base de données
8.1. Les triggers de base de données
8.1.1. Aperçu des triggers

Les triggers sont des blocs PL/SQL s’exécutant implicitement chaque fois qu’un
événement particulier a lieu. Les triggers peuvent être mis en place soit sur
une base de données soit sur une application.

Les triggers de base de données sont exécutés implicitement lorsque qu’un


ordre INSERT, UPDATE ou DELETE (ordres déclenchants) est exécuté sur la
table associée au trigger. Les triggers sont exécutés quelque soit l’utilisateur
connecté ou l’application utilisée. Les triggers de base de données sont
également exécutés implicitement pour les actions de l’utilisateur ou les
actions systèmes de la base de données. Par exemple, lorsque l’utilisateur se
logue ou lorsque qu’un DBA arrête la base de données.

Les triggers de base de données peuvent être définis sur des tables ou sur des
vues. Si une opération DML est effectuée sur une vue, le trigger INSTEAD OF
définit les actions qui auront lieu. Si ces actions incluent des opérations DML
sur des tables, tous les triggers sur la ou les tables de base sont déclenchées

100 Prof: Andy PIERRE, M.Sc


8. Création de triggers de base de données
8.1. Les triggers de base de données
8.1.2. Directives de conception des triggers
L’utilisation de trigger garantit que lorsqu’une opération spécifique est
exécutée, les actions en rapport sont exécutées implicitement et de manière
transparente pour l’utilisateur.
On utilise les triggers de base de données pour des opérations globales et
centralisées qui doivent être déclenchées par des ordres indépendamment de
l’utilisateur ou de l’application ayant émis l’ordre.
Il est préférable de ne pas définir de trigger pour reproduire ou remplacer les
fonctionnalités déjà présentes dans la base de données Oracle. Par exemple, il
ne faut pas définir de trigger implémentant des règles d’intégrité qui peuvent
être mises en place en utilisant des contraintes.
L’utilisation excessive de triggers peut aboutir à des interdépendances
complexes, ce qui peut rendre difficile la maintenance des grosses applications.
Il ne faut utiliser les triggers que si nécessaire et faire attention aux effets
récursifs et en cascades qu’ils peuvent produire.
Un trigger récursif est un trigger contenant une opération DML modifiant la
même table.

101 Prof: Andy PIERRE, M.Sc


8. Création de triggers de base de données
8.1. Les triggers de base de données
8.1.2. Directives de conception des triggers
Un trigger en cascade est un trigger dont l’action entraîne le déclenchement
d’un second trigger et ainsi de suite. Le serveur Oracle autorise l’exécution en
cascade de 32 triggers maximum en même temps, mais on peut limiter le
nombre de triggers en cascade en changeant la valeur du paramètre
d’initialisation de la base de données OPEN_CURSORS, qui par défaut est
initialisé à 50.
Le schéma montre un trigger de base
de données qui vérifie que le salaire
inséré se situe bien dans la tranche
définie. Les valeurs ne respectant pas
le rang de salaire en fonction du type
d’emploi peuvent être soit
rejetées, soit être insérées et
signalées dans une table
d’audit.

102 Prof: Andy PIERRE, M.Sc


8. Création de triggers de base de données
8.1. Les triggers de base de données
8.1.3. Création de triggers
Avant de coder le corps du trigger, il faut décider des paramètres de
ses composantes : la synchronisation du trigger, l’évènement
déclenchant et le type de trigger.
Composante Description Valeurs Possibles

Synchronisation du Définit à quel moment le trigger se déclenche BEFORE


trigger par rapport à l’effet déclenchant AFTER
INSTEAD OF
Evènement Définit quelle opération de manipulation de INSERT
déclenchant données sur la table ou la vue entraîne le UPDATE
déclenchement du trigger DELETE

Type de trigger Définit combien de fois le corps du trigger est Statement


exécuté Row

Corps du trigger Définit les actions qui seront exécutées par le Bloc PL/SQL
trigger complet

103 Prof: Andy PIERRE, M.Sc


8. Création de triggers de base de données
8.2. Les composantes d’un trigger
8.2.1. La synchronisation du trigger
La synchronisation du trigger définit le moment où le trigger sera déclenché.
Elle peut prendre trois valeurs : BEFORE, AFTER, INSTEAD OF.

Un trigger BEFORE exécute le corps du trigger avant l’évènement DML


déclenchant sur la table. Les triggers BEFORE sont utilisés :
Quand l’action du trigger détermine si l’ordre déclenchant est autorisé à
s’exécuter ou pas. Cette situation permet d’éliminer les exécutions inutiles de
l’expression déclenchante et les éventuels ROLLBACK pour les cas où une
expression est levée lors de l’action déclenchante.
Pour modifier les valeurs des colonnes avant d’effectuer un ordre déclenchant
de type INSERT ou UPDATE

104 Prof: Andy PIERRE, M.Sc


8. Création de triggers de base de données
8.2. Les composantes d’un trigger
8.2.1. La synchronisation du trigger
La synchronisation du trigger définit le moment où le trigger sera déclenché.
Elle peut prendre trois valeurs : BEFORE, AFTER, INSTEAD OF.

Un trigger AFTER exécute le corps du trigger après que l’évènement DML


déclenchant se soit produit sur la table. Les triggers AFTER sont utilisés :
Quand on veut que l’action déclenchante soit terminée avant d’exécuter
l’action du trigger.
Quand on veut exécuter plusieurs actions sur un ordre déclenchant
possédant déjà un trigger BEFORE.

Un trigger INSTEAD OF exécute le corps du trigger au lieu de l’ordre


déclenchant. Ce trigger fournit un moyen de modifier des vues qui ne sont pas
directement modifiables par des ordres DML parce que les vues ne sont pas
modifiables par nature. Ainsi il est possible d’écrire des ordres INSERT, UPDATE
et DELETE sur la vue et le trigger INSTEAD OF va agir en transparence pour
exécuter l’action codée directement sur les tables sous-jacentes de la vue.

105 Prof: Andy PIERRE, M.Sc


8. Création de triggers de base de données
8.2. Les composantes d’un trigger
8.2.2. L’évènement déclenchant
Les évènements déclenchants les triggers peuvent être les ordres DML INSERT,
UPDATE et DELETE.
Lorsque l’évènement déclenchant est un ordre UPDATE, il est possible de
définir une liste de colonnes pour identifier celle(s) qui devra être modifiée
pour déclencher le trigger. Il est impossible de spécifier une liste de colonnes
pour les ordres INSERT et DELETE car ils portent sur toute une ligne.
… UPDATE OF sal …

L’évènement déclenchant peut être composé de plusieurs opérations DML :


. . . INSERT or UPDATE or DELETE
. . . INSERT or UPDATE OF job . . .

106 Prof: Andy PIERRE, M.Sc


8. Création de triggers de base de données
8.2. Les composantes d’un trigger
8.2.3. Le type de trigger
Le type de trigger représente le nombre de fois que le corps du trigger
sera exécuté lorsque l’évènement déclenchant se produit. Il peut
prendre deux valeurs : Statement et Row.
Un trigger Statement ne s’exécute qu’une fois pour l’évènement déclenchant
même si aucune ligne n’est concernée. Cette valeur est utilisée pour la valeur
par défaut. Les triggers Statement sont utiles si l’action du trigger ne dépend
pas des données des lignes concernées ou des données fournies par
l’évènement déclenchant lui-même. Par exemple, un trigger qui exécute une
vérification de sécurité complexe sur l’utilisateur courant.

Un trigger Row est un trigger dont le corps s’exécute une fois pour chaque
ligne concernée par l’évènement déclenchant. Si l’évènement déclenchant
n’affecte aucune ligne, le corps du trigger n’est pas exécuté. Les triggers Row
sont utiles lorsque l’action du trigger dépend des données des lignes affectées
ou des données fournies directement par l’évènement déclenchant

107 Prof: Andy PIERRE, M.Sc


8. Création de triggers de base de données
8.2. Les composantes d’un trigger
8.2.4. Le corps du trigger
Le corps du trigger définit toutes les actions qui seront exécutées lors
du déclenchement. Le corps est constitué d’un bloc PL/SQL ou d’un
appelà une procédure. Le bloc PL/SQL peut être contenir des ordres SQL et
PL/SQL, définir des éléments PL/SQL comme des variables, curseurs,
exceptions et autres.

108 Prof: Andy PIERRE, M.Sc


8. Création de triggers de base de données
8.3. La séquence de déclenchement
La séquence de déclenchement correspond à l’ordre dans lequel sont
exécutés la requête et le trigger. Cette séquence dépend de l’option du
type de déclenchement choisi (BEFORE, AFTER, INSTEAD OF) et du
type de trigger (Row ou Statement).
Lorsque le trigger est de type Statement, le trigger n’est exécuté qu’une
seule fois. Si le déclenchement est de type BEFORE, le trigger s’exécutera
d’abord pour ensuite laisser la requête DML s’effectuer.
S’il s’agit d’un trigger AFTER la requête s’exécute et ensuite le trigger prend la
main pour effectuer ses actions. Si le trigger est de type INSTEAD OF le corps
du trigger est exécuté à la place de la requête DML.
Pour un trigger de type Row, le trigger s’exécute une fois par ligne traitée.
Pour un trigger BEFORE, le corps du trigger s’exécute en premier puis la
requête s’exécute sur la première ligne retournée, ensuite le trigger s’exécute
une nouvelle fois, puis la requête s’exécute sur la ligne suivante et ainsi de
suite jusqu’à ce qu’il n’y ait plus de ligne retournée.
Pour un trigger AFTER la démarche est la même, sauf que le corps du trigger
s’exécute après chaque ligne traitée. Lorsque la requête ne retourne qu’une
ligne, la séquence de déclenchement est identique à celle d’un Statement trigger.

109 Prof: Andy PIERRE, M.Sc


8. Création de triggers de base de données
8.4. Création de Statement trigger
8.4.1. Syntaxe de création de Statement triggers
La syntaxe permettant de créer un Statement trigger est la suivante :

CREATE [OR REPLACE] TRIGGER trigger_name


timing
event1 [OR event2 OR event3] ON table_name
trigger_body
Trigger_name : Indique le nom du trigger qui sera créé
Timing : Indique l’instant auquel sera déclenché le trigger en relation
avec l’événement déclenchant : BEFORE , AFTER , INSTEAD OF
Event: Identifie l’opération de manipulation de données qui déclenche
le trigger : INSERT, UPDATE [OF column] , DELETE
Table/view_name : Indique la table ou vue qui sera associée au trigger

Trigger_body : Le corps du trigger définissant les actions qui seront


exécutées par celui-ci. Le corps commence par DECLARE ou
BEGIN et se termine par END ou est un appel à une procédure.

110 Prof: Andy PIERRE, M.Sc


8. Création de triggers de base de données
8.4. Création de Statement trigger
8.4.2. Exemple de Creation de Trigger
Un trigger BEFORE permet d’empêcher l’exécution de certaines
requêtes si une condition n’est pas respectée. On va ainsi créer un
trigger pour restreindre les ordres INSERT sur la table EMP aux heures ouvrées
entre Lundi et Vendredi.
CREATE OR REPLACE TRIGGER secure_emp
BEFORE INSERT ON emp
BEGIN
IF (TO_CHAR (sysdate,’DY’) IN (’SAM’,’DIM’)) OR
(TO_CHAR(sysdate,’HH24’) NOT BETWEEN ’08’ AND ’18’)
THEN RAISE_APPLICATION_ERROR (-20500,
’Insertion dans EMP impossible hors des heures de travail.’);
END IF;
END;
RAISE_APPLICATION_ERROR est une procédure serveur intégrée qui
affiche un message sur le terminal et cause l’échec du trigger. Quand un
trigger de base de données échoue, l’événement déclenchant est
automatiquement annulée (ROOLBACK) par le serveur Oracle.

111 Prof: Andy PIERRE, M.Sc


8. Création de triggers de base de données
8.4. Création de Statement trigger
8.4.3. Utilisation d’attributs conditionnels
Il est possible de combiner plusieurs évènements déclenchant une
seule déclaration grâce aux attributs conditionnels INSERTING, UPDATING et
DELETING à l’intérieur du corps du trigger. Ces attributs sont inclus dans des
expressions conditionnelles de type IF-THEN-ELSE.
On peut par exemple créer un trigger qui restreindra toutes les opérations de
manipulation de données sur la table EMP aux heures de travail entre Lundi et
Vendredi.
CREATE OR REPLACE TRIGGER secure_emp BEFORE INSERT OR UPDATE OR DELETE ON emp
BEGIN
IF (TO_CHAR (sysdate,’DY’) IN (’SAM’,’DIM’)) OR (TO_CHAR (sysdate, ’HH24’) NOT BETWEEN
’08’ AND ’18’) THEN
IF DELETING THEN RAISE_APPLICATION_ERROR (-20502,
‘Suppression de EMP impossible hors des heures de travail.’);
ELSIF INSERTING THEN RAISE_APPLICATION_ERROR (-20500,
‘Insertion dans EMP impossible hors des heures de travail.’);
ELSIF UPDATING (’SAL’) THEN RAISE_APPLICATION_ERROR (-20503,
‘Mise à jour de SAL impossible hors des heures de travail.’);
ELSE RAISE_APPLICATION_ERROR (-20504,
’Mise à jour de EMP impossible hors des heures de travail.’);
END IF;
END IF;
END;
112 Prof: Andy PIERRE, M.Sc
8. Création de triggers de base de données
8.5. Création de Row Triggers
8.5.1. Syntaxe de création d’un Row Trigger
La syntaxe permettant de créer un Row Trigger est la suivante :
CREATE [OR REPLACE] TRIGGER trigger_name
timing
event1 [OR event2 OR event3]
ON table_name
[REFERENCING OLD AS old | NEW AS new]
FOR EACH ROW
[WHEN condition]
trigger_body
Trigger_name : Indique le nom du trigger qui sera créé
Timing :Indique l’instant auquel sera déclenché le trigger en relation avec l’événement
déclenchant : BEFORE, AFTER, INSTEAD OF
Event : Identifie l’opération de manipulation de données qui déclenche le trigger :
INSERT, UPDATE [OF column] , DELETE
Table_name : Indique le table ou vue qui sera associée au trigger
REFERENCING : Spécifie les noms des liens réciproques pour l’ancienne et la nouvelle valeur de
la ligne en cours (les valeurs par défauts sont OLD et NEW)
FOR EACH ROW : Indique que le trigger est un Row trigger
WHEN :Spécifie la restriction du trigger (l’attribut conditionnel est évalué pour chaque ligne afin
de déterminer si le corps du trigger est exécuté ou non)
Trigger_body : Le corps du trigger définissant les actions qui seront exécutées par celui-ci. Le
corps commence par DECLARE ou BEGIN et se termine par END ou est un appel à une procédure

113 Prof: Andy PIERRE, M.Sc


8. Création de triggers de base de données
8.5. Création de Row Triggers
8.5.2. Exemple de création d’un Row Trigger
On peut créer un Row trigger BEFORE afin d’empêcher l’opération
déclenchante de s’exécuter sur chaque ligne concernée lorsqu’une certaine condition
n’est pas respecter. On peut par exemple créer un Row trigger qui n’ autorise qu’a
certains employés de gagner un salaire supérieur à 5000.
CREATE OR REPLACE TRIGGER Control_salaire
BEFORE INSERT OR UPDATE OF sal ON emp
FOR EACH ROW
BEGIN
IF NOT (:NEW.JOB IN (‘MANAGER’ , ‘PRESIDENT’)) AND :NEW.SAL > 5000 THEN
RAISE_APPLICATION_ERROR (-20202, ‘L’employé ne peut pas gagner autant.’);
END IF;
END;
Ce trigger empêche les utilisateurs d’insérer un salaire supérieur à 5000 pour tous les JOB sauf
les MANAGER et PRESIDENT.
Si l’utilisateur essaye d’insérer un salaire supérieur à 5000, le trigger renvoie une erreur :
SQL> UPDATE EMP SET SAL = 6500 WHERE ENAME = ’MILLER’ ;
ERROR at line 1:
ORA-20202: L’employé ne peut pas gagner autant.
Le trigger produit une erreur et ainsi la table EMP n’est pas modifiée.

114 Prof: Andy PIERRE, M.Sc


8. Création de triggers de base de données
8.5. Création de Row Triggers
8.5.3. Utilisation des qualificatifs OLD et NEW
Lorsque l’on utilise un Row Trigger, celui-ci enregistre les valeurs de
plusieurs colonnes avant et après la modification des données en utilisant les
qualificatifs OLD et NEW associés au nom de colonne respectif
Pour l’exemple on va utiliser une table nommée AUDIT_EMP_TABLE. Cette table est
constituée des colonnes user_name, timestamp, id, old_last_name, new_last_name,
old_title, new_title, old_salary,_ new_salary).
CREATE OR REPLACE TRIGGER audit_emp_values
AFTER DELETE OR INSERT OR UPDATE ON emp
FOR EACH ROW
BEGIN
INSERT INTO audit_emp_table (user_name, timestamp, id, old_last_name,
new_last_name, old_title, new_title, old_salary, new_salary)
VALUES (USER, SYSDATE, :OLD.empno, :OLD.ename, :NEW.ename, :OLD.job,
:NEW.job, :OLD.sal, :NEW.sal );
END;
Cette requête crée un trigger qui, pour tout ordre DML sur la table EMP
insérera une ligne d’audit en enregistrant l’ancienne et la nouvelle valeur du
nom, du titre et du salaire

115 Prof: Andy PIERRE, M.Sc


8. Création de triggers de base de données
8.5. Création de Row Triggers
8.5.4. Utilisation des qualificatifs OLD et NEW
Pour pouvoir tester le trigger ci-dessus, il faut d’abord cree la table :

CREATE TABLE audit_table (


user_name VARCHAR2(30),
tablename VARCHAR2(30),
column_name VARCHAR2(30),
del NUMBER(4), ins NUMBER(4),
upd NUMBER(4)
);

Insert into audit_table (user_name, tablename)


Values ('SCOTT','EMP');
Insert into audit_table (user_name, tablename, column_name)
values ('SCOTT','EMP','SAL');

116 Prof: Andy PIERRE, M.Sc


8. Création de triggers de base de données
8.5. Création de Row Triggers
8.5.5. Valeurs de OLD et NEW
Dans un Row Trigger il est possible de faire référence aux valeurs d’une
colonne avant et après le changement dû à un ordre DML en préfixant le
nom de celle-ci du qualificatif OLD ou NEW.
Selon l’opération DML effectuée, les valeurs OLD et NEW ne seront pas les
mêmes :
Opération Valeur de OLD Valeur de NEW
INSERT NULL Valeur Insérée
UPDATE Valeur avant la mise à jour Valeur après la mise à jour
DELETE Valeur avant la suppression NULL
Les qualificatifs OLD et NEW ne sont disponibles que pour les triggers de
type Row.
Il faut préfixer ces qualificatifs de deux points (:) dans tout ordre SQL ou
PL/SQL les utilisant.
Il ne faut pas utiliser de préfixe deux points (:) quand les qualificatifs sont
utilisés dans la condition de restriction WHEN.

117 Prof: Andy PIERRE, M.Sc


8. Création de triggers de base de données
8.5. Création de Row Triggers
8.5.6. Restreindre un trigger de ligne
Grâce à la condition WHEN il est possible de restreindre l’action du trigger aux
lignes conformes à certaines conditions.
Exemple :
CREATE OR REPLACE TRIGGER derive_commission_pct
BEFORE INSERT OR UPDATE OF sal ON emp
FOR EACH ROW
WHEN (NEW.job = ’SALESMAN’)
BEGIN
IF INSERTING THEN :NEW.comm := 0;
ELSIF :OLD.comm IS NULL THEN :NEW.comm := 0;
ELSE :NEW.comm := :OLD.comm * (:NEW.sal/:OLD.sal);
END IF;
END; (Ce trigger est utilisé pour calculer la nouvelle commission quand une ligne
est ajoutée ou modifiée dans la table EMP. )
Si l’on veut assigner des valeurs aux colonnes en utilisant le qualificatif NEW
il faut créer un Row trigger BEFORE. Si l’on essaye de compiler le code de
l’exemple en utilisant un trigger AFTER il se produira une erreur

118 Prof: Andy PIERRE, M.Sc


8. Création de triggers de base de données
8.6. Trigger INSTEAD OF
8.6.1. Intérêt des triggers INSTEAD OF
On utilise les triggers INSTEAD OF pour modifier des données sur lesquelles
un ordre DML a été effectué alors qu’elles font partie d’une vue non
modifiable. Ces triggers exécutent les opérations INSERT, UPDATE et DELETE
directement sur les tables sous-jacentes à la vue. Lorsque l’on écrit un ordre INSERT,
UPDATE ou DELETE sur une vue, le trigger INSTEAD OF agit en transparence en tâche
de fond pour exécuter les bonnes actions en remplacement.
On appelle ces triggers INSTEAD OF car ; contrairement aux autres triggers, le serveur
Oracle déclenche le trigger au lieu d’exécuter l’expression déclenchante. Le type
INSTEAD OF est un Row trigger.
Si une vue est constituée de plus d’une table, une insertion sur celle-ci peut entraîner
une insertion dans une table et une mise à jour dans une autre. Donc on doit écrire un
trigger INSTEAD OF qui se déclenche lors de l’exécution d’un ordre INSERT. A la
place de l’ordre INSERT original, le corps du trigger est exécuté ce qui résulte en une
insertion dans une table et une mise à jour dans l’autre.
Lorsqu’une vue est modifiable et qu’elle possède un trigger INSTEAD OF, le trigger aura
la priorité d’exécution et donc exécutera le corps du trigger pour chaque ordre DML.
Les triggers INSTEAD OF ne sont disponibles que sur l’édition Entreprise de Oracle.

119 Prof: Andy PIERRE, M.Sc


8. Création de triggers de base de données
8.6. Trigger INSTEAD OF
8.6.2. Création d’un trigger INSTEAD OF
La syntaxe pour la création de trigger INSTEAD OF est la suivante :
CREATE [OR REPLACE] TRIGGER trigger_name
INSTEAD OF
event1 [OR event2 OR event3] ON view_name
[REFERENCING OLD AS old | NEW AS new]
[FOR EACH ROW]
trigger_body
Trigger_name : Indique le nom du trigger
INSTEAD OF: Indique que le trigger portera sur une vue
Event : Précise le type d’opération de manipulation de données qui déclenchera le
trigger. Cette valeur peut être : INSERT ,UPDATE [OF colonne] , DELETE
View_name : Indique la vue associée au trigger
REFERENCING : Spécifie le nom des liens de corrélation pour les nouvelles et
anciennes valeurs. (Par défaut ces valeurs sont OLD et NEW)
[FOR EACH ROW] :Désigne le trigger en tant que Row trigger. Les triggers INSTEAD
OF ne peuvent être que des Row triggers donc cette clause est optionnelle.
Trigger_body Le corps du trigger définit les actions qui seront exécutées par le
trigger. Ce bloc peut être un bloc PL/SQL avec une clause DECLARE ou BEGIN et le mot
clés END ou un appel à une procédure

120 Prof: Andy PIERRE, M.Sc


8. Création de triggers de base de données
8.7. Gestion des triggers
8.7.1. Activation, Desactivation et Suppression des triggers
Lorsque l’on a créé un trigger, il existe des commandes permettant de les
manipuler afin de les activer, les désactiver et les recompiler.
Lorsqu’un trigger est créé, il est automatiquement activé
On peut désactiver un trigger, pour effectuer une opération que celui-ci interdit
par exemple, on peut utiliser la commande ALTER TRIGGER en précisant le nom du
trigger.
On peut également désactiver tous les triggers de la base de données en une
seule commande en utilisant la syntaxe ALTER TABLE.
ALTER TRIGGER trigger_name DISABLE | ENABLE
ALTER TABLE table_name DISABLE | ENABLE ALL TRIGGERS

Pour recompiler explicitement un trigger invalide on utilise la commande ALTER


TRIGGER.
ALTER TRIGGER trigger_name COMPILE
Pour Suprimer un Trigger
DROP TRIGGER trigger_name;

121 Prof: Andy PIERRE, M.Sc


Le langage PL/SQL
1. Introduction
2. Structure d’un bloc PL/SQL
3. Variables et Types de Données en PL/SQL
4. Traitement des données en PL/SQL
5. Procédures et fonctions en PL/SQL
6. Les curseurs en PL/SQL
7. Les Packages en PL/SQL
8. Utilisation des Triggers en ORACLE
9. Gestion des erreurs en PL/SQL

122 Prof: Andy PIERRE, M.Sc


9. Gestion des Exceptions
Gestion d’exception, pourquoi?
La section Exception
Types d’exceptions
Déclenchement d’exceptions
Traitement des exceptions
Communication d’erreurs entre client et serveur
L’exception WHEN_NO_DATA_FOUND
Gestionnaire d’exceptions comme ordre IF
RAISE EXCEPTION

123 Prof: Andy PIERRE, M.Sc


9. Gestion des Exceptions
En PL/SQL toutes les erreurs de toute nature sont traitées comme
des exceptions.
Une exception peut être:
Une erreur générée par le système (“mémoire insuffisante”,
“index dupliqué”)
Une erreur induite par une action de l’utilisateur
Un avertissement (warnings) de l’application à l’utilisateur.

PL/SQL détecte et traite les erreurs grâce à une architecture de


gestionnaires d’exceptions. Le mécanisme des gestion
d’exceptions permet de séparer proprement le code de
traitement d’erreur des ordres exécutables (modèle de
programmation par événements).

124 Prof: Andy PIERRE, M.Sc


9. Gestion des Exceptions
Lever les exceptions
Il existe deux façons de lever une exception :
- Une erreur Oracle survient et l'exception associée est
automatiquement levée. Par exemple, si aucune ligne n'est
retournée dans un ordre SELECT, l'erreur ORA-01403
survient, alors le langage PL/SQL lève l'exception
NO_DATA_FOUND.
- Le programmeur lève une exception explicitement en
utilisant l'ordre RAISE dans un bloc. L'exception levée doit
être une exception définie par le développeur ou une
exception prédéfinie

125 Prof: Andy PIERRE, M.Sc


9. Gestion des Exceptions
Traiter les exceptions
Il existe deux façons de traiter une exception :
- L'attraper (la capturer) avec un traitement ("handler").
- La propager dans l'environnement.
Si une exception est levée dans la section exécutable d'un
bloc, l'exécution du bloc rejoint ("branches") le traitement
correspondant à l'exception dans la section de gestion des
exceptions du bloc. Si le moteur PL/SQL traite avec succès
l'exception, alors l'exception n'est pas propagée au bloc
"père" ni à l'environnement. Dans ce cas, le bloc PL/SQL se
termine alors avec succès.

126 Prof: Andy PIERRE, M.Sc


9. Gestion des Exceptions
Si une exception est levée dans la section exécutable
d'un bloc et qu'il n'existe pas de traitement pour
cette exception. Le bloc PL/SQL se termine avec une
erreur d'exécution ("failure") et l'exception est
propagée dans l'environnement

127 Prof: Andy PIERRE, M.Sc


9. Gestion des Exceptions
Les types d'exception
Il existe trois types d'exception :
- Les erreurs du serveur Oracle prédéfinies
- Les erreurs du serveur Oracle non prédéfinies
- Les erreurs définies par le développeur
Les erreurs du serveur Oracle prédéfinies
correspondent approximativement aux 20 erreurs qui
apparaissent le plus souvent dans un bloc PL/SQL.
Elles ne sont pas déclarées et sont levées
automatiquement par le serveur Oracle.

128 Prof: Andy PIERRE, M.Sc


9. Gestion des Exceptions
Les erreurs du serveur Oracle non prédéfinies
correspondent à toutes les autres erreurs standard
qui peuvent apparaître dans un bloc PL/SQL. Elles
sont déclarées dans la section déclarative et sont
automatiquement levées par le serveur Oracle.
Les erreurs définies par l'utilisateur
correspondent à des conditions que le développeur a
jugé anormales. Elles sont déclarées dans la section
déclarative et sont levées explicitement par le
développeur dans la section exécutive.

129 Prof: Andy PIERRE, M.Sc


9. Gestion des Exceptions
Capturer les exceptions
Le développeur peut capturer n'importe quel erreur en incluant
une routine correspondante dans la section de gestion des
exceptions d'un bloc PL/SQL. Chaque section de traitement
(appelé "handler") est constitué d'une clause WHEN qui
spécifie une exception, suivie d'une séquence d'ordres
exécutée lorsque l'exception est levée.

130 Prof: Andy PIERRE, M.Sc


9. Gestion des Exceptions
Syntaxe :
EXCEPTION
WHEN exception1 [OR exception2...] THEN
statement1;
statement2;

[WHEN exception3 [OR exception4...] THEN


statement1;
statement2;
...]
[WHEN OTHERS THEN
statement1;
statement2;
...]

131 Prof: Andy PIERRE, M.Sc


9. Gestion des Exceptions
Capturer des erreurs prédéfinies du serveur Oracle
Pour capturer une erreur prédéfinie par le serveur Oracle, son nom doit être
référencé dans la routine de traitement des exceptions.
Exemple :
BEGIN
EXCEPTION
WHEN NO_DATA_FOUND THEN
statement1;
statement2;
WHEN TOO_MANY_ROWS THEN
statement1;
WHEN OTHERS THEN
statement1;
statement2;
END;
132 Prof: Andy PIERRE, M.Sc
9. Gestion des Exceptions
Capturer des erreurs prédéfinies du serveur Oracle
Tableaux des principales exceptions prédéfinies :
Nom de l'exception No de l'erreur du serveur Oracle Description
CURSOR_ALREADY_OPEN ORA-06511 Un curseur a essayé d'être ouvert.
DUP_VAL_ON_INDEX ORA-00001 Une valeur existante a essayé d'être insérée.
INVALID_CURSOR ORA-01001 L'opération sur un curseur illégale s'est produite.
INVALID_NUMBER ORA-01722 La conversion de chaînes de caractères en nombre a échoué.
LOGIN_DENIED ORA-01017 La connexion à Oracle a été réalisé avec un nom d'utilisateur invalide ou un mot de passe.
NO_DATA_FOUND ORA-01403 Un ordre SELECT ne retourne aucune donnée.
NOT_LOGGED_ON ORA-01012 Un programme PL/SQL interroge une base de données sans être connecté à Oracle.
PROGRAM_ERROR ORA-06501 Le moteur PL/SQL a un problème interne.
STORAGE_ERROR ORA-06500 Il n'y a pas assez de mémoire pour le moteur PL/SQL ou la mémoire est corrompu.
TIMEOUT_ON_RESSOURCE ORA-00051 "Time-out occured while Oracle is waiting for a ressource"
TOO_MANY_ROWS ORA-01422 Un ordre SELECT retourne plus d'une ligne.
VALUE_ERROR ORA-06502 Une erreur arithmétique, de conversion, de troncation ou de contrainte de taille est apparu.
ZERO_DEVIDE ORA-01476 Une division par zéro a été tenté.

133 Prof: Andy PIERRE, M.Sc


9. Gestion des Exceptions
Capturer les exceptions définies par l'utilisateur
Le langage PL/SQL permet à l'utilisateur de définir ses propres exceptions.
Les exceptions définies par l'utilisateur doivent être :
1. déclarées dans la section déclarative d'un bloc PL/SQL.
Syntaxe :
exception EXCEPTION; --exception est le nom de l'exception donné par le
développeur.
2. levées explicitement dans la section exécutable avec l'ordre RAISE.
Syntaxe :
RAISE exception; -- exception est le nom de l'exception déclarée par le
développeur.
3. référencées avec dans une routine de la section de gestion des exceptions.

134 Prof: Andy PIERRE, M.Sc


9. Gestion des Exceptions
Capturer les exceptions définies par l'utilisateur
3. Référencées avec dans une routine de la section de gestion des exceptions.
Syntaxe :
WHEN exception THEN
statements; -- exception est le nom de l'exception déclarée et levée
explicitement précédemment.

135 Prof: Andy PIERRE, M.Sc


9. Gestion des Exceptions
Syntaxe des erreurs utilisateurs:
DECLARE
Nom_erreur EXCEPTION attribution d’un nom à l’erreur
BEGIN
IF ….
THEN RAISE nom_erreur; déclenchement de l’erreur
EXCEPTION
WHEN nom_erreur THEN… traitement de l’erreur
END;

Remarque: on sort du bloc après le traitement de l’erreur.

136 Prof: Andy PIERRE, M.Sc


9. Gestion des Exceptions
Capturer les exceptions définies par l'utilisateur
ACCEPT Numero PROMPT Numero Employe:
DECLARE
E_invalid_EmpNo EXCEPTION;
BEGIN
UPDATE EMP SET Sal=5300 WHERE Empno = &Numero;
IF SQL%NOTFOUND THEN
RAISE E_invalid_EmpNo;
END IF;
COMMIT;
EXCEPTION
WHEN E_invalid_EmpNo THEN
DBMS_OUTPUT.PUT_LINE(‘No Employe Incorrect.');
END;

137 Prof: Andy PIERRE, M.Sc


9. Gestion des erreurs
Syntaxe des erreurs ORACLE non prédéfinie:
DECLARE
Nom_erreur EXCEPTION attribution d’un nom à l’erreur
PRAGMA EXCEPTION_INIT(nom_erreur, code_erreur)
--le nom de l’erreur est associé à un code erreur.
…..
BEGIN

l’erreur Oracle est détectée par le système
EXCEPTION
WHEN nom_erreur THEN… traitement de l’erreur
END;

Remarque: on sort du bloc après le traitement de l’erreur.

138 Prof: Andy PIERRE, M.Sc


9. Gestion des erreurs
Syntaxe des erreurs ORACLE prédéfinie:

Certaines erreurs ORACLE ont déjà un nom. Il est


donc inutile de les déclarer comme
précédemment. On utilise leur nom dans la
section EXCEPTION.

139 Prof: Andy PIERRE, M.Sc


9. Gestion des erreurs
Syntaxe des erreurs ORACLE prédéfinie (suite)
DECLARE
….
BEGIN

l’erreur Oracle est détectée par le système
EXCEPTION
WHEN nom_erreur THEN… traitement de l’erreur
END;

Exemple d’erreurs predefinies:


• DUP_VAL_ON_INDEX
• NO_DATA_FOUND
• …
• OTHERS

140 Prof: Andy PIERRE, M.Sc


9. Gestion des erreurs
Complément

• SQLCODE renvoie le code de l’erreur courante


(numérique)

• SQLERRM[(code_erreur)] renvoie le libellé de


l’erreur courante ou le libellé de l’erreur dont le
numéro est passé en paramètre

141 Prof: Andy PIERRE, M.Sc


Exercices PL/SQL
Les erreurs

Écrire un fichier qui mette à jour l’âge des pilotes de la table pilote.
Traiter les anomalies:
• pilote de moins de 20 ans
• Pour les autres erreurs qui pourraient se produire: les traiter globalement.

142 Prof: Andy PIERRE, M.Sc


Bibliographie
1. Oracle PL/SQL Programming 5nd Edition Covers Oracle11g
2. Oracle PL/SQL Programming 3nd Edition Covers Oracle 9i
3. Programmation PL/SQL

By Steven Feuerstein with Bill Pribyl


Edition : O’Reilly & Associates

143 Prof: Andy PIERRE, M.Sc