Vous êtes sur la page 1sur 111

LE LANGAGE PL/SQL :

Partie des concepts de SQL3


1° PARTIE
Réalisé par: Pr . Mohamed AZZOUAZI

1
PLAN DU COURS
 Première partie
• Introduction au langage PL/SQL
• Les variables
• Traitements conditionnels
• Traitements répétitifs
• Les curseurs
• Gestion d’exceptions
• Procédures, Fonctions et Paquetages
 Deuxième partie
• Triggers
• Types Abstraits
– Attributs : stockés et dérivés
– Méthodes, Encapsulation, Héritage, Généricité
– OID, Collections
2
1. Préambule : Qu'est ce que SQL3 ?
 prochain standard SQL pour 98 ?
 implémenté en partie dans certains produits
 extensions importantes :
• extension procédurale - proche d’ADA (ex: PL/SQL
d’Oracle)
• au relationnel : assertions, triggers
• vers l’objet : UDT (dans Oracle 8)

3
2. INTRODUCTION AU LANGAGE PL/SQL

2.1. Aperçu sur le langage


2.1.1. Comparaison avec SQL2
2.2. Le bloc PL/SQL
2.2.1. Structure d'un bloc
2.2.2. Exemple

4
2.1. Aperçu sur le langage

 Extension du moteur SQL du SGBD Oracle depuis sa


version 6
 Bloc de programme
 Déclaration / stockage de procédures et de fonctions
 Création de packages
 Utilisable au niveau :
– du serveur ou du client
– en interactif ou depuis des outils (Forms, embedded SQL, ...)

5
2.1.1. Comparaison avec SQL2

 SQL :
• langage assertionnel et non procédural
 PL/SQL :
• langage procédural, qui intègre des ordres SQL
– SELECT, INSERT, UPDATE, DELETE
– INSERT, UPDATE, DELETE
– gestion des transactions : COMMIT, ROLLBACK, SAVEPOINT
• langage à part entière comprenant
– Définition de variables, constantes, expressions, affectations
– Traitements conditionnels, répétitifs
– Traitement des curseurs (et de collections)
– Traitement des erreurs et d’exceptions
– Modularité (sous-programmes)
6
2.2. Structure d'un bloc
 Le bloc
* interprète un ensemble de commandes
* est composé de 3 sections :

DECLARE
déclaration variables, constantes,
exceptions et curseurs
BEGIN [nom-bloc]
instructions SQL et extensions
EXCEPTION
Traitement des exceptions
END ; ou END nombloc;

7
2.2.2. Exemple : CONTRÔLE de STOCK
Prompt nom du produit désiré
Accept nom-prod
Declare
qte-stock number (5) ;
Begin
Select quantité into qte-stock From Stock
Where produit= '&nom-prod' ;
If qte-stock > 0
Then Update stock Set quantité = quantité - 1
Where produit = '&nom-prod' ;
Insert into Ventes Values (&nom-prod ||'VENDU');
Else Insert into Ventes
Values (&nom-prod || 'demandé');
end if;
commit;
end;
8
3. Les variables

3.1. Types de variables utilisées


3.2. Déclaration des variable
3.3. Initialisation et visibilité

9
3.1. Types de variables utilisées
Variables locales :
 de type simple : type de base ou booléen
 faisant référence à la métabase
 de type composé : Tableau, Record

Variables extérieures :
 variables d’un langage hote (ex: C) (préfixées par :)
 paramètres (ex: SQL interactif) (préfixées par &)
 champs d'écrans (Forms)

10
3.2. Variables de type simple

 Exemple :
Declare
nom char (15) ;
salaire number (7, 2) ;
embauche DATE ; DD-MON-YY
réponse boolean ; valeur : TRUE, FALSE, NULL

11
3.2. Variables sur la métabase
 reprend :
• soit le même type qu'une colonne dans une table
• soit la même structure qu'une ligne dans une table
• soit le même type qu'une variable précédemment définie
 syntaxe :
nom_var1 table.colonne%TYPE
nom_var2 table%ROWTYPE
nom_var3 nom_var1%TYPE
 exemple :
nom emp.ename%TYPE ;
enreg emp%ROWTYPE ;
commi number (7, 2);
salaire commi%TYPE ;
12
3.2. Le type TABLE

 Déclaration du type :
TYPE nom_type IS TABLE OF
{type_colonne | nom_table.nom_col%TYPE}
[NOT NULL] INDEX BY BINARY_INTEGER ;

 Déclaration de la variable :
nom_var nom_type

13
3.2. Le type RECORD

 Déclaration de type :
TYPE nom_type IS RECORD
{nom_champ1 {type_champ |
nom_table.nom_col%TYPE } [NOT NULL] ,
nom_champ2 {type_champ |
nom_table.nom_col%TYPE } [NOT NULL] ,
... ) ;

 Déclaration de variable :
nom_var nom_type

14
3.3. Initialisation et visibilité

 initialisation par :
• opérateur :=, sections Declare, Begin et Exception
• ordre Select ... Into ... dans la section Begin
• traitement d'un curseur
 L'opérateur := :
nom char (10) := 'MILLER';
reponse boolean := TRUE;
 constante :
pi CONSTANT number (7,2) := 3.14;
 interdire les valeurs non renseignées : clause NOT
NULL
debut number NOT NULL :=10;
15
3.3. Initialisation et visibilité

 L'ordre SELECT :
Select col1, col2
Into var1, var2
From table
[Where condition] ;
 Règle :
• la clause INTO est obligatoire
• le Select ne doit ramener qu'une ligne
 visibilité : bloc de déclaration + blocs imbriqués

16
3.3. Exemple

Declare
nom_emp char (15) ;
salaire emp.sal%TYPE ;
commission emp.comm%TYPE ;
nom_départ char (15) ;
Begin
Select ename, sal, comm, dname
Into nom_emp, salaire, commission, nom_départ
Fom emp, dept
Where ename = 'MILLER' and
emp.deptno=dept.deptno;
...
End; 17
4. Traitements conditionnels

 Définition :
• exécution d'instructions suivant le résultat d'une condition
 Syntaxe :
If condition1 Then traitement1 ;
elsif condition2 then traitement2 ;
else traitement3 ;
end if;
 Opérateurs utilisés dans les conditions :
• ce sont les mêmes que dans SQL

18
4.2. Exemple
Declare
emploi char (10) ;
nom char (15) := 'MILLER' ;
mes char (30) ;
Begin
Select job Into emploi From emp Where ename=nom;
If emploi is null then mes := nom || 'n"a pas d"emploi';
elsif emploi = 'SALESMAN'
then update emp
set comm = 1000 where ename=nom;
mes := nom || 'commission modifiée' ;
else update emp
set comm = 0 where ename = nom ;
mes := nom || 'pas de commission' ;
end if;
insert into resultat values (mes) ; commit ; end ; 19
5. Traitements répétitifs

 Définition :
• possibilité d'effectuer des traitements répétitifs : clause
LOOP
 Quatre types de boucles :
• la boucle de base
• la boucle FOR
• la boucle WHILE
• la boucle CURSOR ... FOR

20
5.2. La boucle de base

 syntaxe :
LOOP [label]
instructions ;
END LOOP [label] ;
 sortie de boucle :
EXIT [label] [WHEN condition]

21
5.2. La boucle de base

 Exemple :
Declare

nbre number := 1 ;
Begin
Loop

Insert into resultat values (nbre);


nbre := nbre + 1
Exit when nbre > 10 ;
End loop ;
End;
22
5.3. La boucle FOR

 Syntaxe :

For indice In [Reverse] exp1 ... exp2 Loop

instructions ;
End Loop ;

23
5.3. La boucle FOR
 Exemple
Declare

fact Number := 1 ;
Begin

For i in 1..9 Loop

fact := fact * i ;
End loop ;
Insert into resultat values (fact, 'FACTORIELLE9') ;
End;

24
5.4. La boucle while

 exécution tant que condition vérifiée


 Syntaxe :
While condition Loop

instructions ;
End loop ;

25
5.4. La boucle while

 exemple : reste de 7324 div 9


Declare

reste number := 7324 ;


Begin

While reste >= 9 loop


reste := reste - 9 ;
end loop ;
insert into resultat values (reste, 'Reste de la division');
End ;

26
5.5. L'instruction GOTO

 syntaxe :
GOTO nom_etiquette ;
 Exemple :
DECLARE
seuil number := 1000 ;
mini number ;
BEGIN
SELECT min(ventes) INTO mini FROM clients;
IF mini > seuil THEN GOTO suite ;
...
suite ... ;
END 27
6. Les curseurs en PL/SQL

6.1. Definition et types


6.2. Etapes d'utilisation d'un curseur implicite
6.3. Attributs d'un curseur
6.4. Simplification d'écriture
6.5. Curseur paramétré
6.6. La clause CURRENT OF

28
6. Les curseurs en PL/SQL

 6.1. Définition
• zone de mémoire de taille fixe utilisée par le noyau Oracle
pour analyser et interpréter tout ordre SQL.

 Deux types de curseurs :


• le curseur implicite : généré et géré par le noyau pour
chaque ordre SQL d'un bloc
• le curseur explicite : généré et géré par l'utilisateur pour
traiter un ordre SELECT qui ramène plusieurs lignes

29
6.2. Utilisation d'un curseur explicite

 4 étapes :
• Déclaration du curseur.
• Ouverture du curseur.
• Traitement des lignes.
• Fermeture du curseur.

30
6.2. Déclaration d'un curseur explicite
 se fait dans la section Déclare
 Syntaxe :
Cursor nom_curseur is ordre_select;
 Exemple :
Declare
cursor dept_10 is
select ename, sal From emp
where deptno=10 order by sal ;
Begin ... End ;

31
6.2. Ouverture d'un curseur explicite
 l'ouverture déclanche :
• l'allocation mémoire du curseur,
• l'analyse syntaxique et sémantique du select
• le positionnement de verrous éventuels
 l'ouverture se fait dans la section Begin
 syntaxe : OPEN nom_curseur;

32
6.2. Exemple de curseur explicite
 déclaration et ouverture :
declare
cursor dept_10 is
select ename, sal from emp
where deptno=10 order by sal ;
begin
... ;
open dept_10 ;
... ;
end ;

33
6.2. Traitement des lignes
 les lignes ramenées sont traitées une par une,la
valeur de chaque colonne doit être stockée dans une
variable réceptrice.
 Syntaxe :

Fetch nom_curseur into liste_variables ;

 Le Fetch ramène une ligne à la fois.

34
6.2. Exemple

Declare
cursor dept_10 is select ename, sal from emp
where deptno = 10 order by sal ;
nom emp.ename%TYPE ;
salaire emp.sal%TYPE ;
Begin
Open dept_10 ;
Loop
Fetch dept_10 into nom, salaire ;
If salaire > 2500
then insert into résultat values (nom,salaire);
end if;
exit when salaire = 5 000 ;
end loop ;
End ;
35
6.2. Fermeture d'un curseur explicite
 Syntaxe :

CLOSE nom_curseur ;

 action : libère la place mémoire

36
6.2. Exemple
Declare
cursor dept_10 is select ename, sal from emp
where deptno = 10 order by sal ;
nom emp.ename%TYPE ;
salaire emp.sal%TYPE ;
Begin
Open dept_10 ;
Loop
Fetch dept_10 into nom, salaire ;
If salaire > 2500
then insert into résultat values (nom,salaire);
end if;
exit when salaire = 5 000 ;
end loop ;
close dept_10 ;
End ;
37
6.3. Les attributs d'un curseur

 Définition : indicateurs sur l'état d'un curseur.


• %FOUND : dernière ligne traitée
• %NOTFOUND : id
• %ISOPEN : ouverture d'un curseur
• %ROWCOUNT : nombre de lignes déjà traitées

39
6.3.1. Attribut %FOUND (resp.
%NOTFOUND)

 type : booléen
 curseur implicite : SQL%FOUND ou %NOTFOUND
 curseur explicite : nom_curseur%FOUND ou
%NOTFOUND

TRUE : le dernier FETCH a ramené (resp. n ’a pas ramené)


une ligne

FALSE : plus de ligne (resp. il y a encore des lignes)

40
6.3.1. Exemple
Declare
cursor dept_10 is select ename, sal from emp
where deptno = 10;
nom emp.ename%TYPE ;
salaire emp.sal%TYPE ;
Begin
Open dept_10 ;
Fetch dept_10 into nom, salaire ;
While dept_10%FOUND
Loop
If salaire > 2500
then insert into résultat values (nom,salaire);
end if;
Fetch dept_10 into nom, salaire ;
end loop ;
close dept_10 ;
End ; 41
6.3.2. Exemple
Declare
cursor dept_10 is select ename, sal from emp
where deptno = 10;
nom emp.ename%TYPE ;
salaire emp.sal%TYPE ;
Begin
Open dept_10 ;
Loop
Fetch dept_10 into nom, salaire ;
Exit when dept_10%NOTFOUND ;
If salaire > 2500
then insert into résultat values (nom,salaire);
end if;
end loop ;
close dept_10 ;
End ; 42
6.3.3. Attribut %ISOPEN

 type : booléen
 curseur implicite : SQL%ISOPEN
Oracle referme les curseurs après utilisation.
 curseur explicite : nom_curseur%ISOPEN
TRUE : le curseur est ouvert

43
6.3.3. Exemple
Declare
cursor dept_10 is select ename, sal from emp
where deptno = 10;
nom emp.ename%TYPE ;
salaire emp.sal%TYPE ;
Begin
If not (dept_10%ISOPEN) then Open dept_10 ; end if;
Loop
Fetch dept_10 into nom, salaire ;
Exit when dept_10%NOTFOUND ;
If salaire > 2500
then insert into résultat values (nom,salaire);
end if;
end loop ;
close dept_10 ;
End ;
44
6.3.4. Attribut %ROWCOUNT

 type : numérique
 curseur implicite : SQL%ROWCOUNT
• Insert, Update, Delete : nbre de lignes ramenées

• Select :
– 0 : ne ramène aucune ligne
– 1 : ramène exactement 1 ligne
– 2 : ramène plus d'une ligne
 curseur explicite : nom_curseur%rowcount

• nbre de lignes ramenées par le Fetch

45
6.3.4. Exemple
Declare
cursor dept_10 is select ename, sal from emp
where deptno = 10;
nom emp.ename%TYPE ;
salaire emp.sal%TYPE ;
Begin
Open dept_10 ;
Loop
Fetch dept_10 into nom, salaire ;
Exit when dept_10%NOTFOUND or
dept_10%ROWCOUNT > 15;
If salaire > 2500
then insert into résultat values (nom,salaire);
end if;
end loop ;
close dept_10 ;
End ; 46
6.4. Simplification d'écriture

 déclaration de variables :
Declare

cursor nom_curseur is ordre_select ;


nom_struct nom_curseur%Rowtype ;
 éléments de la structure identifiés par :
nom_struct.nom_colonne
 structure renseignée par le Fetch :
Fetch nom_curseur into nom_struct ;

47
6.4. Exemple
Declare
cursor c1 is select ename, sal + nvl (comm, 0) saltot
from emp;
c1_rec c1%ROWTYPE ;
Begin
Open c1;
Loop
Fetch c1into c1_rec ;
Exit when c1%NOTFOUND ;
If c1_rec.saltot > 2500
then insert into résultat
values (c1_rec.ename,c1_rec.saltot);
end if;
end loop ;
close c1;
End ;
48
6.4. Simplification d'écriture

 curseurs dans les boucles.


For nom_rec in nom_curseur loop
traitement
end loop ;
 Application à l’exemple précédent
Declare
cursor c1 is select ename, sal + nvl (comm, 0) saltot from emp;
Begin
For C1_rec in c1 loop
If c1_rec.saltot > 2500 then
insert into résultat values (c1_rec.ename,c1_rec.saltot);
end if;
end loop ;
End 49
6.4. Exemple
Declare
cursor dept_10 is select ename, sal from emp
where deptno = 10 ;
Begin
For nom_rec in dept_10
Loop
If nom_rec.sal > 2500
then insert into resultat
values (nom_rec.ename, nom_rec.sal) ;
end if;
end loop ;
End ;

50
6.4. Simplification d'écriture

 Déclaration du curseur dans la boucle FOR :


 Syntaxe :
For nom_record in (SELECT ...)
Loop
Traitement ;
End Loop ; évite la déclaration du curseur.

51
6.4. Exemple
Begin
For nom_rec in ( Select ename, sal from emp
Where deptno = 10 )
Loop
If nom_rec.sal > 2500
Then Insert into résultat
Values ( nom_rec.ename,
nom_rec.sal);
End if ;
End loop ;
End ;

52
6.5. Curseur paramétré

 Objectif : réutiliser un même curseur avec des


valeurs différentes dans un même bloc PL/SQL
 Syntaxe :
Declare
cursor nom_curseur (par1 type, par2 type, ...) is ordre_select

Begin
Open nom_curseur (val1, val2, ...) ;

53
6.5. Exemple
Prompt Nombre de salaires
Accept nb
Declare
Cursor grosal is select distinct sal from emp
order by sal desc ;
Cursor c1 (psal number) is select ename, sal, empno
from emp where sal = psal ;
Begin
For vgrosal in grosal
loop
exit when grosal%rowcount > &nb ;
For employe in c1 (vgrosal.sal)
Loop
Insert into resultat values (employe.sal,
employe.ename || 'de numero : ' || to_char (employe.empno));
End loop ; End loop ; end ;
Select num salaire, chaine employe from resultat;

54
6.6. La clause CURRENT OF

 Objectif :
• Accéder directement en modification ou en suppression à la
ligne ramenée par Fetch
• il faut verouiller les lignes lors de la déclaration du curseur (
... For Update of nom_col ...)

55
6.6. Exemple 1
Declare
Cursor c1 is select ename, sal from emp
for update of sal ;
Begin
For c1_rec in c1
Loop If c1_rec.sal > 1 500
Then Insert into resultat
values (c1_rec.ename, c1_rec.sal * 1.3);
Update emp set sal = sal * 1.3
Where Current of c1 ; end if,
end loop ; end;

56
6.6. Exemple 2
Alter table dept add (budget number) /
Declare
Cursor c_dept is select deptno, budget from dept
for update of budget ;
Begin
For ligne_dept in c_dept
Loop Update dept set budget =
(Select sum (sal) from emp
Where deptno= ligne_dept.deptno)
Where current of c_dept ; end loop ;
End ;
/ Select * From dept ; Rollback ;

57
7. Gestion des erreurs

7.1. Section EXCEPTION


7.2. Anomalie progr. utilisateur
7.3. Erreur Oracle

58
7.1. Section Exception
 Notion d'exception : traitement d'erreurs
 Types d'erreurs :
• erreurs internes Oracle (Sqlcode <> 0)
• erreurs programme utilisateur
 Règles à respecter :
• définir et donner un nom à chaque erreur
• associer ce nom à la section Exception (partie declare)
• définir le traitement dans la partie Exception

59
7.2. Anomalies du programme

 Syntaxe :
Declare
nom_erreur exception ;
...
Begin
...
If (anomalie) then raise nom_erreur ;
...
Exception When nom_erreur then (traitement) ;

 Sortie du bloc après exécution du traitement

60
7.2. Exemple
Declare
pas_comm EXCEPTION ;
salaire emp.sal%TYPE ;
commi emp.comm%TYPE ;
numéro emp.empno%TYPE ;
Begin
Select sal, comm, empno into salaire, commi,
numéro from emp where empno = :num_emp ;
If commi = 0 or commi is null
Then raise pas_comm
Else (traitement) ; end if ;
Exception When pas_comm
then insert into resultat values
(numéro, salaire, 'pas de comm') ;
End ;

61
7.3.Gestion d’erreurs
Syntaxe :
Declare ...
nom_erreur exception ;
pragma exception_init (nom_err, code_err) ;
...
Begin
...
si erreur Oracle, passage automatique dans la
section Exception.
Exception When nom_erreur then (traitement) ;
[When others then (traitement) ; ]

62
7.3. Exemple
Exemple : traiter l'erreur 1002 : Fetch out of sequence

Declare
fetch_out_of exception;
pragma exception_init (fetch_out_of, - 1002);
Begin
Traitement du curseur
...
Exception
When fetch_out_of then (traitement erreur) ;
End ;

63
7.4. Diagnostic d’erreurs

 SQLCODE : renvoie le code de l'erreur courante


(valeur numérique)

 SQLERRM [(code_erreur)] :
• renvoie le libellé de l'erreur courante.

64
7.4. Exemple
Declare
nom char (10) ;
code number ;
lg number ;
mess char (50) ;
Begin
Select ename into nom from emp
Where empno = 9999 ;
Exception
When others then code := sqlcode ;
mess := sqlerrm ; lg := length (mess) ;
Insert into resultat values (code, lg, mess) ;
Commit ;
End ;

65
8. Sous-programmes

8.1. Déclaration
8.2. Les procédures
8.3. Les fonctions
8.4. Les packages

66
8.1. Déclaration

 Procédures ou fonctions stockées dans le schéma


• offrent la modularité
• profitent de toute la gestion du dictionnaire (droits,...)
• intégrés au moteur SQL => plus efficaces
 Syntaxe
Procedure son_nom (arg [in|out|IN OUT] Type,...) IS
ou Function son_nom (arg [in|out|IN OUT] Type,...) Return Type IS
[declarations locales]
Begin
Traitement
[Exception ...]
End son_nom;
67
8.2. Exemple de procédure
procedure offre_prime (id_emp number) is -- et pas number(4)
prime REAL;
err_comm EXCEPTION;
Begin
Select comm*0.25 Into prime
From emp Where empno=id_emp;
IF prime IS NULL THEN
RAISE err_comm;
ELSE
UPDATE paiement SET paie=paie+prime WHERE empno=id_emp;
END IF;
EXCEPTION
When err_comm THEN ...
END offre_prime;
68
8.2. Surcharge
 Même nom de sous-programme pour 2
implémentations différentes
procedure initialize (tab OUT tab_date, n integer) IS
Begin For i IN 1..n Loop Tab(i):= SYSDATE;
End Loop;
End initialize;
procedure initialize (tab OUT tab_reel, n integer) IS
Begin For i IN 1..n Loop Tab(i):= 0.0;
End Loop;
End initialize;
...

69
8.3. Exemple de fonction
Function salaire_ok (salaire REAL, grade REAL) Return BOOLEAN
is
sal_min, sal_max REAL;
Begin
Select losal, hisal Into sal_min, sal_max
From grille_salaires Where tranche= grade;
Return (salaire>=sal_min) AND (salaire<= sal_max);
END salaire_ok;

 Utilisation :
IF sal_ok(tel_sal, tel_grade) THEN ...

70
8.4. Exemple de package
package actions_emp is -- spécification
procedure offre_prime (id_emp number);
procedure embauche (id_emp number, nom char, ...);
procedure licencie (id_emp number);
END actions_emp;

package BODY actions_emp is


procedure offre_prime (id_emp number) IS ...
procedure embauche (id_emp number, nom char, ...) IS
Begin INSERT INTO emp (...)
End embauche;
procedure licencie (id_emp number) IS ...
END action_emp;

71
LE LANGAGE PL/SQL :
Partie des concepts de SQL3
2° PARTIE

72
9. Déclencheurs (Triggers)

9.1. Définition
9.2. Caractéristiques
9.3. Utilisations
9.4. Déclencheurs par ordre
9.5. Déclencheurs par ligne
9.4. Statuts d’un déclencheur
73
9.1. Définition
 Programme stocké et invoqué implicitement sur un
événement affectant la BD
 Séquence de règles de production déclenchées à
l'apparition d'un événement prédéfini
Règles de production

TYPE ECA (Event-Condition-Action)


Sur Evénement
Si Condition
Alors Action
74
9.1. Définition (Evènement)
 EVENEMENT :
• Dépend des transitions de l'état de la base :
– Avant ou après Insertion de données,
– Avant ou après Mise à jour de données,
– Avant ou après Suppression de données.

• Evénement élémentaire ou composite : Conjonction d'événements


élémentaires (Ensemble d'événements élémentaires reliés par
l'opérateur OR )

75
9.1. Définition (Condition et Action)

 CONDITION : (WHEN)
– Prédicat Optionnel

 ACTION :
. Block PL/SQL (exécuté après l'apparition de l'événement si
la condition éventuelle est satisfaite
. Peut contenir des Procédures Cataloguées
. Peut activer des déclencheurs en cascade: maximum 32 ou
limité par le paramètre MAX_OPEN_CURSOR

76
9.2. Caractéristiques
 Granularité :
. déclencheur par ordre (orienté ensemble) : par défaut
. déclencheur par ligne (orienté instance) :
FOR EACH

 Condition autorisée uniquement pour le déclencheur par ligne


• Prise en compte de l'état de la base : uniquement pour déclencheur
par ligne
– Antérieur à l'événement : OLD
– ultérieur à l'événement: NEW
• Spécification d'une liste de colonnes pour déclencheur de type Mise à
jour

77
9.3. Utilisations des triggers

 Le déclencheur renforce des fonctionnalités std de


ORACLE7 pour:
• les valeurs calculées : alimentation de colonnes dérivées, de
variables globales à la base, ...
• les règles de gestion complexes,
• l'intégrité référentielle dans une architecture réparties
• la duplication de tables,
• une sécurité plus sophistiquée : accès à la base sur des critères
temporels (date, heure), sur le contenu de table, ...
• un audit plus sophistiqué : statistiques sur les accès aux tables,
• etc.

78
9.4. Déclencheur par ordre (= table)
 Syntaxe :
CREATE/REPLACE TRIGGER nom_trigger
BEFORE/AFTER événement1 [OR événement2 [OR événement3 ]]
ON nom_table
Bloc PL/SQL
AVEC :
événement1, événement2, événement3 = INSERT ou
UPDATE [OF nom_col1,...,nom_coln] ou DELETE

79
9.4. Déclencheur par ordre (Utilisation)

 Utilisé si le traitement porte globalement sur l'ensemble des


lignes de la table,

• Un déclencheur BEFORE par ordre permet d'éviter l'exécution d'un


nombre important de traitements si certaines conditions ne sont pas
respectées,

• Un déclencheur AFTER par ordre permet de vérifier si les opérations


se sont exécutées correctement, de réaliser des calculs, un audit, ...

80
9.4. Déclencheur par ordre (Exemple1)
 Interdire l'insertion, la mise à jour et la suppression de
données de la table emp après 18h
CREATE Trigger nmj_emp
Before insert or update or delete on emp
Begin
IF (TO_CHAR (sysdate, 'HH24')) > 18
THEN
IF INSERTING THEN
Raise_application_error (-20501, 'Insertion Interdite ');
ELSEIF UPDATING THEN
Raise_application_error (-20502, 'Mise à jour Interdite ');
ELSE
Raise_application_error (-20503, 'Suppression Interdite ')
END IF;
END IF;
END; 81
9.4. Déclencheur par ordre (Exemple2)
 Nombre de requêtes de modification intervenues sur la
colonne salaire SAL de la table emp.

CREATE TRIGGER nb_maj_sal


AFTER UPDATE OF SAL ON emp
BEGIN
UPDATE Surv_emp
SET cpt_maj=cpt_maj+1
WHERE code_op = 'MAJ'
END;

82
9.5. Déclencheur par ligne
 Syntaxe :
Create/Replace TRIGGER nom_trigger
Before/After événement1
[OR événement2 [or événement3 ]] On nom_table
For each Row [When condition]
Bloc PL/SQL

Avec :
événement1, événement2, événement3 : INSERT/
UPDATE [OF nom_col1,...,nom_coln]/ DELETE

condition : prédicat exécuté pour chaque ligne


83
9.5. Déclencheur par ligne

 Utilisé si le traitement porte sur chacune des lignes de la table


• Calcul d'une colonne à partir d'autre colonnes,
• Duplication de données,
• audit sophistiqué
• ...
 Exemple 1:
• Contrôle d'intégrité référentielle pour le numéro de département
(Deptno) avant chaque insertion ou mise à jour sur la table Emp (table
fille) par rapport au contenu de la table Dept (table mère).
 Exemple 2:
• Comptabiliser le nombre de lignes ajoutées, mises à jour ou
supprimées dans la table emp.
84
9.5. Déclencheur par ligne (Exemple 1)
CREATE TRIGGER cont_depart
Before Insert OR Update of Dept On emp
For each row
DECLARE
Num_dept Integer;
CURSOR REC_DEPT (dn Number) IS
Select deptno from dept where deptno =dn
for Update of deptno;
BEGIN
Open REC_DEPT(:new.deptno);
Fetch REC_DEPT into Num_dept;
IF REC_DEPT%NOTFOUND THEN
Raise_Aplication_Error (-2000, 'Numéro de département Invalide')
END IF;
CLOSE REC_DEPT;
END;
85
9.5. Déclencheur par ligne (Exemple 2)
CREATE Trigger nmj_emp
After insert or update or delete on emp
For each row
Begin
IF INSERTING THEN
UPDATE Surv_emp
SET cpt_maj=cpt_maj+1
WHERE code_op = 'AJOUT';
ELSEIF UPDATING THEN
UPDATE Surv_emp
SET cpt_maj=cpt_maj+1
WHERE code_op = 'MAJ';
ELSE
UPDATE Surv_emp
SET cpt_maj=cpt_maj+1
WHERE code_op = 'SUP';
END IF;
END IF;
END; 86
9.5. Déclencheur par ligne (Exemple 3)

Create TRIGGER sal_de_dept -- attribut dérivé d’une autre


table
AFTER DELETE OR INSERT or UPDATE of deptno ON emp
FOR EACH ROW BEGIN
IF DELETING OR (UPDATING AND :old.deptno != :new.deptno)
THEN UPDATE dept SET sal_total = :sal_total - :old.sal WHERE
deptno = :old.deptno;
END IF;
IF INSERTING OR (UPDATING AND :old.deptno != :new.deptno)
THEN UPDATE dept SET sal_total = :sal_total + :new.sal
WHERE deptno = :new.deptno;
END IF;
IF (UPDATING AND :old.deptno = :new.deptno AND :old.sal != :new.sal)
THEN UPDATE dept SET sal_total = :sal_total - :old.sal +
:new.sal WHERE deptno = :new.deptno;
END IF;
87
9.6. Statuts d’un déclencheur
 Enable : actif (dès sa création)
ALTER TRIGGER nom_trigger DISABLE
OU
ALTER TABLE nom_table ENABLE ALL TRIGGERS
 Disable : désactivé
ALTER TRIGGER nom_trigger DISABLE
OU
ALTER TABLE nom_table DISABLE ALL TRIGGERS
ATTENTION !!!
• Une utilisation abusive de déclencheurs sur une base de données
peut déboucher sur :
– des inter dépendances très complexes entre tables et par conséquent, sur
une application difficilement maintenable.
– des temps de réponse non raisonnables pour l'utilisateur. 88
NOMBRE DE DECLENCHEURS POUR UNE TABLE

Un type d'événement (INSERT, UPDATE ou DELETE)


peut activer 4 déclencheurs sur une table :
. Before par table,
. After par table,
. Before par ligne,
. After par ligne.

12 combinaisons possibles

Plusieurs déclencheurs du même type sur une table déconseillés

89
Exécution pour un type d ’évènement
0. Activation de l'ordre SQL (INSERT, UPDATE, DELETE)
1. Exécution du déclencheur BEFORE par table
2. Pour chaque ligne de la table
a. exécution du déclencheur BEFORE par ligne
b. verrouillage de la ligne suivit du traitement et le contrôle des
contraintes d'intégrité
c. exécution du déclencheur AFTER par llgne et contrôle des contraintes
d'intégrité
3. Exécution de l'ordre SQL et contrôle des contraintes d'intégrité
4. Exécution du déclencheur AFTER par table

92
MODELE D'EXECUTION

 Le modèle est récursif et permet la prise en compte des


déclencheurs en cascade

Exemple :
Un déclencheur BEFORE par ligne effectue une mise à
jour qui active
un déclencheur AFTER

93
1. Le déclencheur BEFORE par ligne est activé et déclenche l'ordre
UPDATE
2. Le déclencheur AFTER est activé par l'ordre UPDATE
a. le traitement de ce déclencheur est
exécuté complètement
b. le contrôle des contraintes
d'intégrité est réalisé sur les tables
affectées par ce traitement
3. le traitement du déclencheur BEFORE par ligne est achevé
4. le contrôle des contraintes d'intégrité est réalisé sur les tables
affectées par ce dernier traitement

94
MODELE D'EXECUTION : Transactions imbriquées

 L'ensemble des traitements suivants doit aboutir pour que l'ordre


SQL déclenchant soit validé :

• chacune des actions activées dans les déclencheurs en cascade,


• l'ordre SQL déclenchant,
• le contrôles de l'ensemble des contraintes d'intégrités impliquées

 AU MOINDRE PROBLEME RENCONTRE,

• UN ROLLBACK EST DECLENCHE AUTOMATIQUEMENT POUR


L'ENSEMBLE DES TRANSACTIONS

95
MODELE D'EXECUTION

ATTENTION AUX EVENTUELS


DECLENCHEURS RECURSIFS

EXEMPLE :
Existence d'un Ordre Update d'une table dans son déclencheur
AFTER par table de type Update.

96
RESTRICTIONS

 Pour sauvegarder une cohérence de données :

1. Pas de mise à jour de colonnes ayant une contrainte d'intégrité de type:


Primary Key, Foreign Key ou Unique
sur les tables sollicitées par l'ordre SQL déclenchant , excepté pour un
déclencheur BEFORE par ligne de type INSERT

2. Pas de lecture ou modification de la table concernée par le


déclencheur.

 Les ordres SQL Commit, Rollback et Savepoint sont interdits.

97
COMPILATION

 Compilation automatique à chaque appel, si le


déclencheur ne réside pas déjà dans le shared pool
(contrairement aux procédures et fonctions d'ORACLE, le
code du déclencheur n'est pas stocké dans la base de
données).

 Compilation manuelle :
ALTER TRIGGER nom_trigger COMPILE

 Préconisation pour de bonnes performances :


Utilisation de procédures dans le déclencheur

98
Gestion des Déclencheurs
Suppression automatique avec la suppression de la table

Privilèges Sur le déclencheur:


. Dévelloppeur :
Create Trigger, Alter Table
. Utilisateur :
Privilège INSERT, UPDATE ou DELETE sur la table concernée

Vues du dictionnaire de données :


USER_TRIGGERS ALL_TRIGGERS
DBA_TRIGGERS

99
10. Types abstraits
(Abstract Data Types ou ADT)
10.1. Définition
10.2. Attributs
10.3. Méthodes
10.4. Encapsulation
10.5. Héritage, Généricité
10.6. OID
10.7. Collection 100
10.1. Définition

 Extension des types définis en standard


• augmente la puissance de modélisation
• permet de définir des types complexes
• permet l’intégration relationnel/objet (ORDBMS)
 Caractéristiques
• Une table peut posséder des attributs d’un type abstrait
– un tuple contient des valeurs complexes ou des références
vers des objets
• Introduit l’héritage et la généricité
– création de sous-types
– création de types paramétrés (templates)
• Offre des collections et permet leur manipulation simplement

101
10.2. Attributs

 Attributs stockés
• déclarés en spécifiant leur nom et leur type
• définissent une fonction implicite de même nom
• options possibles : DEFAULT, NOT NULL, CHECK
 Attributs virtuels (ou dérivés)
• déclarés en spécifiant leur nom suivi du mot-clé VIRTUAL
• l’ADT doit contenir une fonction qui calcule sa valeur et
éventuellement des routines de sa mise à jour
• options possibles : CHECK
 Propriétés des attributs
• Un attribut peut être : UPDATABLE, READ ONLY ou
CONSTANT
• Pour un attribut virtuel UPDATABLE, on doit spécifier sa 102
10.3. Méthodes

 Différents types
• Constructeur : crée et initialize une instance d’ADT
• Destructeur : détruit une instance d’ADT
• Acteur : toute autre méthode
 Utilisation
• Si le constructeur ou le destructeur n’est pas défini , une
fonction implicite est fournie automatiquement
• Une définition d’ADT peut comprendre plusieurs
constructeurs / destructeurs. Ils peuvent être surchargées

103
10.4. Encapsulation

 protection d’attributs et de méthodes


• PUBLIC : accessible sans restriction
• PRIVATE : n’est accessible qu’au sein de la définition de
l’ADT
• PROTECTED : peut être accédé au sein de la définition de
l’ADT et de ses sous-types
 protection par défaut
• PUBLIC
• Hérite de la protection si sous-type

104
Exemple
CREATE TYPE personne
( name char (30) NOT NULL,
adresse char(50),
PRIVATE date_naiss DATE
CHECK (date_naiss < SYSDATE),
PUBLIC age UPDATABLE VIRTUAL
GET WITH age SET WITH init_age,

CONSTRUCTOR FUNCTION personne (un_nom VARCHAR, ...)


RETURNS personne ;
BEGIN
NEW :p;
SET :p.name = :un_nom;
...
RETURN :p;
END;
END FUNCTION; 105
Exemple (suite)
DESTRUCTOR FUNCTION suppr_personne (p personne) RETURNS
personne ;
BEGIN
...
DESTROY :p;
RETURN :p;
END;
END FUNCTION;

FUNCTION age (p personne) RETURNS REAL;


RETURN ...;
END FUNCTION;
PROCEDURE init_age (p personne, ...);
BEGIN ...
END;
END PROCEDURE;
...) 106
10.5. Héritage / Généricité
 Héritage : Sous-types
• de 1 ou plusieurs types (super-types) => héritage multiple
• hérite des attributs (stockés et virtuels) et des méthodes
• peut avoir des attributs et méthodes supplémentaires
 Généricité : Types paramétrés ou génériques (templates)
• ADT ayant des paramètres
• un paramètre peut être un type ou une valeur
• les types générés sont crées après invocation avec les paramètres
• il est possible d’imbriquer des invocations de template dans un type
généré

107
Exemple - sous-type
CREATE TYPE etudiant UNDER personne
( num-etudiant INTEGER,
ecole VARCHAR,
annee_etude INTEGER,
...
FUNCTION resultat (e etudiant) RETURNS char(1) ;
BEGIN
...
RETURN ...;
END;
END FUNCTION
);

108
Exemple - type générique
CREATE TYPE TEMPLATE point (:T TYPE)
( xval :T,
yval :T,
...
CONSTRUCTOR FUNCTION point (:X :T, :Y :T) RETURNS
GENTYPE ;
...
END FUNCTION
);
CREATE TYPE TEMPLATE liste (:T TYPE)
(...);

Declare
P1 point (INTEGER);
P2 point (REAL);
L liste (POINT(INTEGER)); 109
10.6. Identifiant d’objets (Object Identifier -
OID)
 Chaque instance d’ADT a généralement un OID
• identifiant unique attribué par le système (généré à la création de
l’instance)
• ne fait pas partie de la valeur elle-même
• peut être visible (matérialisé par une chaine de caractères) ou non
visible
– par défaut : WITH OID NOT VISIBLE
• Il est possible de créer un ADT dont les instances n’ont pas d’OID

Exemple :
CREATE TYPE adresse WITHOUT OID
(numero NUMBER
rue char(30)
);
110
10.7. Collections
 Définis comme des templates
• SET
• LIST
• MULTISET
– Super-type des premiers
• Définis en intension ou en extension
– Exemples : SET (1,2,5), LIST (1,2,3,1,2)
• Le test d’égalité est basé sur la valeur
• La notion de TABLE et de RECORD dérivent de SQL2
– une table est UPDATABLE et diffère peu de SET ou de LIST
• Les collections peuvent être pures ou hybrides (regroupant des
objets de types différents)

111
Exemple
CREATE TYPE personne
( name char (30),
prenom set ( char(30) ),
enfants list ( personne ),
...)

CREATE table population ( individu personne)

112
10.7. Requêtes sur collections
 La manipulation des collections :
• est un prolongement de celle des tables dans SQL2

Exemple :
SELECT nom (individu)
FROM population
WHERE ‘François’ IN ( SELECT * FROM enfant (individu) );

• Il est en plus possible d’appliquer une fonction définie sur un type T


aux arguments de type collection
– le résultat est une collection d’éléments de type R, si R est le type
résultat de la fonction

113
Standard en évolution
 Autre composants du langage :
• Interfaces : avec le client (CLI) ou inter-systèmes (RDA, TP)
• Gestion de transactions
• Gestion de Règles
• Gestion de données temporelles, multi-media, etc.

 Autres propositions
• OQL (de l’ODMG) = pur objet
• Avantage de SQL3 : besoin de continuïté / relationnel

 Avenir :
• Déterminé par la bataille des éditeurs SGBD (R ou OO)
– Critère = commercial et politique d’abord

114

Vous aimerez peut-être aussi