Upload
az-za
View
312
Download
1
Embed Size (px)
Citation preview
PL/SQL et Triggers
Pourquoi PL/SQL ?
PL/SQL = PROCEDURAL LANGUAGE/SQL
SQL est un langage non procédural
Les traitements complexes sont parfois difficiles à écrire
si on ne peut utiliser des variables et les structures de
programmation comme les boucles et les alternatives
On ressent vite le besoin d’un langage procédural pour
lier plusieurs requêtes SQL avec des variables et dans les
structures de programmation habituelles
2 PL/SQL et Triggers
Principales caractéristiques de PL/SQL
Extension de SQL : des requêtes SQL cohabitent avec les
structures de contrôle habituelles de la programmation
structurée (blocs, alternatives, boucles)
La syntaxe ressemble au langage Ada ou Pascal
Un programme est constitué de procédures et de
fonctions
Des variables permettent l’échange d’information entre
les requêtes SQL et le reste du programme
3 PL/SQL et Triggers
Utilisation de PL/SQL
PL/SQL peut être utilisé pour l’écriture des procédures
stockées et des triggers
Oracle accepte aussi le langage Java
Il convient aussi pour écrire des fonctions utilisateurs qui
peuvent être utilisées dans les requêtes SQL (en plus des
fonctions prédéfinies)
Il est aussi utilisé dans des outils Oracle
Ex : Forms et Report
4 PL/SQL et Triggers
Normalisation du language
Langage spécifique à Oracle
Tous les SQBG ont un langage procédural
TransacSQL pour SQLServer,
PL/pgSQL pour Postgresql
Procédures stockées pour MySQL depuis 5.0
Tous les langages L4G des différents SGBDs se
ressemblent
5 PL/SQL et Triggers
Utilisation de PL/SQL
6
Le PL/SQL peut être utilisé sous 3 formes
Un bloc de code, exécuté comme une unique commande SQL,
via un interpréteur standard (SQL+ ou iSQL*PLus)
un fichier de commande PL/SQL
un programme stocké(procédure, fonction, package ou trigger)
PL/SQL et Triggers
Le langage PL/SQL
Blocs
8
Un programme est structuré en blocs d’instructions de 3
types :
Procédures anonymes
Procédures nommées
Fonctions nommées
Un bloc peut contenir d’autres blocs
PL/SQL et Triggers
Structure d’un programme PL/SQL
9
DECLARE
-- définition des variables
BEGIN
-- code du programme
EXCEPTION
-- code de gestion des erreurs
END;
PL/SQL et Triggers
Déclaration, initialisation des variables
10
Identificateurs Oracle :
30 caractères au plus
commence par une lettre
Peut contenir lettres, chiffres, _, $ et #
pas sensible à la casse
Portée habituelle des langages à blocs
Doivent être déclarés avant d’être utilisés
PL/SQL et Triggers
Déclaration, initialisation des variables
11
Déclaration et initialisation
Nom_variable type_variable := valeur;
Initialisation
Nom_variable := valeur;
Déclaration multiple interdite
Exemples:
age integer;
nom varchar(30);
dateNaissance date;
ok boolean:= true;
PL/SQL et Triggers
Initialisation de variables
12
Plusieurs façons de donner une valeur à une variable :
Opérateur d’affectation
n :=
Directive INTO de la requête SELECT
Exemples :
dateNaissance:= ’10/10/2004’;
SELECT nome INTO nom
FROM emp
WHERE matr= 509;
PL/SQL et Triggers
SELECT … INTO …
13
select expr1, expr2,…into var1, var2,…met des valeurs
de la BD dans une ou plusieurs variables expr1, expr2, …
Le select ne doit renvoyer qu’une seule ligne
Avec Oracle il n’est pas possible d’inclure un select sans
«into» dans une procédure : pour ramener plusieurs
lignes les curseurs.
PL/SQL et Triggers
Le type de variables
14
VARCHAR2
Longueur maximale : 32767 octets
Syntaxe: Nom_variable VARCHAR2(30);
Exemple:
name VARCHAR2(30); name VARCHAR2(30) := ’farid’;
NUMBER(long,dec)
Long : longueur maximale
Dec : longueur de la partie décimale
Exemple:
num_tel number(10); farid number(5,2)=142.12;
PL/SQL et Triggers
Le type de variables (2)
15
DATE
Nom_variable DATE;
Par défaut DD-MON-YY (18-DEC-02)
Fonction TO_DATE Exemple :
start_date := to_date(’29-SEP-2003’,’DD-MON-YYYY’);
start_date := to_date(’29-SEP-2003:13:01’,’DD-MON-
YYYY:HH24:MI’);
BOOLEAN
TRUE, FALSE ou NULL
PL/SQL et Triggers
Déclaration %TYPE et %ROWTYPE
16
On peut déclarer qu’une variable est du même type
qu’une colonne d’une table ou (ou qu’une autre variable) :
Exemple :
nom emp.nome.%TYPE;
Une variable peut contenir toutes les colonnes d’une
ligne d’une table
Exemple :
employe emp%ROWTYPE;
déclare que la variable employe contiendra une ligne de la table emp
PL/SQL et Triggers
Exemple d’utilisation
17
DECLARE
employe emp%ROWTYPE;
nom emp.nome.%TYPE;
BEGIN
SELECT * INTO employe
FROM emp
WHERE matr= 900;
nom := employe.nome;
employe.dept:= 20;
…
INSERT into emp VALUES employe;
END
PL/SQL et Triggers
Commentaires
18
--Pour une fin de ligne
/* Pour plusieurs
lignes */
PL/SQL et Triggers
PL /SQL : les principales
commandes
Test conditionnel
20
IF-THEN
IF l_date > ’11-APR-03’ THEN
l_salaire := l_salaire * 1.15;
END IF;
IF-THEN-ELSE
IF l_date > ’11-APR-03’ THEN
l_salaire := l_salaire * 1.15;
ELSE l_salaire := l_salaire * 1.05;
END IF;
PL/SQL et Triggers
Test conditionnel
21
IF-THEN-ELSIF IF l_nom = MOHAMED’ THEN
l_salaire := l_salaire * 1.15;
ELSIF l_nom = ‘AHMED’ THEN
l_salaire := l_salaire * 1.05;
END IF;
CASE CASE sélecteur
WHEN expression1 THEN résultat1
WHEN expression2 THEN résultat2
ELSE résultat3
END;
PL/SQL et Triggers
Test conditionnel
22
Exemple :
val := CASE os
WHEN ‘WINDOWS’ THEN ‘MICROSOFT’
WHEN ‘LEOPARD’ THEN ‘APPLE’
ELSE ‘Unix’
END;
PL/SQL et Triggers
Les boucles
23
LOOP
instructions exécutables;
END LOOP;
Obligation d’utiliser la commande EXIT
WHILE condition LOOP
instructions exécutables;
END LOOP;
PL/SQL et Triggers
Les boucles
24
FOR variable IN debut..fin
LOOP
instructions;
END LOOP;
PL/SQL et Triggers
Affichage
25
Activer le retour écran
set serveroutput on size 10000
Affichage
dbms_output.put_line(chaîne);
Utilise || pour faire une concaténation
PL/SQL et Triggers
Exemple
26
set serveroutput on --sous SQLPLUS
DECLARE
i number(2);
BEGIN
FOR i IN 1..5 LOOP
dbms_output.put_line(‘Nombre: ’|| i );
END LOOP;
END;
PL/SQL et Triggers
Exemple
27
DECLARE
nb integer;
BEGIN
delete from emp where matr in (600, 610);
nb := sql%rowcount; --curseur sql
dbms_output.put_line('nb = ' || nb);
END;
PL/SQL et Triggers
Exemple
28
DECLARE
compteur number(3);
i number(3);
BEGIN
select count(*) into compteur from clients;
FOR i IN 1..compteur LOOP
dbms_output.put_line('Nombre : ' || i );
END LOOP;
END;
PL/SQL et Triggers
Les curseurs
Les curseurs
30
Toutes les requêtes SQL sont associées à un curseur
Ce curseur représente la zone mémoire utilisée pour
parser(analyser) et exécuter la requête
Le curseur peut être implicite (pas déclaré par
l’utilisateur) ou explicite
Les curseurs explicites servent à retourner plusieurs
lignes avec un select
PL/SQL et Triggers
Les curseurs
31
Tous les curseurs ont des attributs que l’utilisateur peut
utiliser
%ROWCOUNT: nombre de lignes traitées par le
curseur
%FOUND: vrai si au moins une ligne a été traitée par la
requête ou le dernier fetch
%NOTFOUND: vrai si aucune ligne n’a été traitée par
la requête ou le dernier fetch
%ISOPEN: vrai si le curseur est ouvert (utile seulement
pour les curseurs explicites)
PL/SQL et Triggers
Les curseurs
32
Les curseurs implicites
Les curseurs implicites sont tous nommés SQL
Exemple :
DECLARE
nb_lignes integer;
BEGIN
delete from emp where dept= 10;
nb_lignes:= SQL%ROWCOUNT;
…
PL/SQL et Triggers
Les curseurs
33
Les curseurs explicites
Pour traiter les select qui renvoient plusieurs lignes
Ils doivent être déclarés
On les utilise dans une boucle FOR
Utilisation implicite des instructions OPEN, FETCH et CLOSE
PL/SQL et Triggers
Les curseurs
34
Les curseurs explicites
DECLARE
nom varchar2(30);
CURSOR c_nom_clients IS
SELECT nom,adresse FROM clients;
BEGIN
FOR le_client IN c_nom_clients
LOOP
dbms_output.put_line('Employé: ' || UPPER(le_client.nom) ||' Ville : '|| le_client.adresse);
END LOOP;
END;
PL/SQL et Triggers
Les curseurs
35
Curseurs paramétrés
Un curseur paramétré peut servir plusieurs fois avec des
valeurs des paramètres différentes
On doit fermer le curseur entre chaque utilisation de
paramètres différents (sauf si on utilise «for »qui ferme
automatiquement le curseur)
PL/SQL et Triggers
Les curseurs
Environnement de bases de données 36
Curseurs paramétrés
DECLARE
CURSOR c(p_dept integer) is
select dept, nome from emp where dept= p_dept;
BEGIN
FOR employe in c(10)LOOP
dbms_output.put_line(employe.nome);
END LOOP;
FOR employe in c(20) LOOP
dbms_output.put_line(employe.nome);
END LOOP;
END;
Les exceptions
Les exceptions
Environnement de bases de données 38
Une exception est une erreur qui survient durant une
exécution
2 types d’exception :
prédéfinie par Oracle
définie par le programmeur
Saisir les exceptions
Environnement de bases de données 39
Une exception ne provoque pas nécessairement l’arrêt du
programme si elle est saisie par un bloc (dans la partie
«EXCEPTION »)
Les exceptions prédéfinies
Environnement de bases de données 40
NO_DATA_FOUND
Quand Select into ne retourne aucune ligne
TOO_MANY_ROWS
Quand Select into retourne plusieurs lignes
VALUE_ERROR
Erreur numérique
ZERO_DIVIDE
Division par zéro
OTHERS
Toutes erreurs non interceptées
Traitement des exceptions
PL/SQL et Triggers 41
BEGIN
…
EXCEPTION
WHEN NO_DATA_FOUND THEN
. . .
WHEN TOO_MANY_ROWS THEN
. . .
WHEN OTHERS THEN--optionnel
. . .
END;
Les exceptions Utilisateur
42
Elles doivent être déclarées avec le type EXCEPTION
On les lève avec l’instruction RAISE
PL/SQL et Triggers
Exemple d’exception utilisateur
43
DECLARE
salaire numeric(8,2);
salaire_trop_bas EXCEPTION;
BEGIN
select sal into salaire from emp where matr= 50;
if salaire < 300 then
RAISE salaire_trop_bas;
end if;
EXCEPTION
WHEN salaire_trop_bas THEN
dbms_output.put_line(‘Salaire trop bas’);
WHEN OTHERS THEN
dbms_output.put_line(SQLERRM);
END;
PL/SQL et Triggers
Exemple d’exception utilisateur
44
ACCEPT X PROMPT (‘Veuillez saisir la matricule’);
DECLARE
--identifiant cmd.id%TYPE;
CURSOR MON_CURSEUR(&X integer) IS
select * from cmd,emp where emp.matricule=X
AND emp.id_client = cmd.id_client;
BEGIN
--select id_client into identifiant from emp where matr= X;
FOR commande in MON_CURSEUR(&X)LOOP
dbms_output.put_line(commande.libelle);
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line(‘Pas de commandes trouvées.’);
END;
PL/SQL et Triggers
Procédures et Fonctions
Bloc anonyme ou nommé
46
Un bloc anonyme PL/SQL est un bloc «DECLARE –
BEGIN –END »comme dans les exemples précédents
Dans SQL*PLUS on peut exécuter directement un bloc
PL/SQL anonyme en tapant sa définition
Le plus souvent, on crée plutôt une procédure ou une
fonction nommée pour réutiliser le code
PL/SQL et Triggers
Procédures sans paramètres
47
create or replace procedure list_nom_clients
IS
BEGIN
DECLARE
nom varchar2(30);
CURSOR c_nom_clients IS select nom,adresse from clients;
BEGIN
FOR le_client IN c_nom_clients LOOP
dbms_output.put_line('Employé: '
|| UPPER(le_client.nom)
||' Ville : '
|| le_client.adresse);
END LOOP;
END;
END;
PL/SQL et Triggers
Procédures avec paramètre
48
create or replace procedure list_nom_clients
(ville IN varchar2,
result OUT number)
IS
BEGIN
DECLARE
--CURSOR c_nb_clients IS
select count(*) INTO nombre
from clients where adresse=ville;
BEGIN
result := nombre – 5;
RETURN result;
END;
END;
IN : en lecture seule
OUT : en écriture seule
IN OUT : en lecture/écriture
PL/SQL et Triggers
Récupération des résultats sous SQL+
49
Déclarer une variable
SQL> variable nb number;
Exécuter la fonction
SQL> execute list_nom_clients('paris',:nb)
Visualisation du résultat
SQL> print
Description des paramètres
SQL> desc nom_procedure
Une variable globale s’utilise avec le
préfixe :
PL/SQL et Triggers
Fonctions sans paramètres
50
create or replace function nombre_clients
return number
IS
BEGIN
DECLARE
i number;
CURSOR get_nb_clients IS select count(*) from clients;
BEGIN
open get_nb_clients;
fetch get_nb_clients INTO i;
return i;
END;
END;
Exécution: select nombre_clients() from dual
Déclaration du type de retour de la
fonction
PL/SQL et Triggers
Fonctions avec paramètres
51
Create or replace
Function euro_to_fr(somme IN number)
return number
IS
taux constant number:= 6.55957;
BEGIN
return somme * taux;
END;
Seuls les paramètres IN (en lecture
seule) sont autorisés pour les fonctions
PL/SQL et Triggers
Procédures et fonctions
52
Suppression de procédures ou fonctions
DROP PROCEDURE nom_procedure
DROP FUNCTION nom_fonction
Table système contenant les procédures et fonctions :
user_source
PL/SQL et Triggers
Compilation, exécution et utilisation
53
Compilation
Sous SQL*PLUS, il faut taper une dernière ligne contenant «/»pour compiler une procédure ou une fonction
Exécution
Sous SQL*PLUS on exécute une procédure PL/SQL avec la commande EXECUTE :
EXECUTE nomProcédure(param1, …);
Utilisation
Les procédures et fonctions peuvent être utilisées dans d’autres procédures ou fonctions ou dans des blocs PL/SQL anonymes
Les fonctions peuvent aussi être utilisées dans les requêtes SQL
PL/SQL et Triggers
Triggers
Triggers
Création de triggers
56
Triggers ou déclencheurs
pour les Bases de Données Actives
E(vènement)-C(ondition)-A(ction)
Evènements : Insert, Delete, Update
Actions : une ou plusieurs actions SQL
PL/SQL et Triggers
Différents type de triggers
57
Trigger Ordre
Before, After
Trigger Ligne
For Each Row
Before, After, Instead of
PL/SQL et Triggers
Création de triggers
58
Exemple :
CREATE TRIGGER nom
BEFORE DELETE OR INSERT OR UPDATE ON
table
FOR EACH ROW
WHEN (new.empno>0)
DECLARE ............ <<<<déclarations>>>>
BEGIN
............ <<<< bloc d'instructions PL/SQL>>>>
END;
PL/SQL et Triggers
Le nom du trigger
59
doit être unique dans un même schéma
peut être le nom d'un autre objet (table, vue, procédure)
mais à éviter
PL/SQL et Triggers
Option BEFORE/AFTER
60
elle précise le moment de l'exécution du trigger
les triggers AFTER row sont plus efficaces que les
BEFORE row parce qu'ils ne nécessitent pas une double
lecture des données.
PL/SQL et Triggers
Définition du trigger
61
Elle comprend le type d'instruction SQL qui déclenche le
trigger :
DELETE, INSERT, UPDATE
On peut en avoir une, deux ou les trois.
Pour UPDATE, on peut spécifier une liste de colonnes. Dans
ce cas, le trigger ne se déclenchera que si l'instruction UPDATE
porte sur l'une au moins des colonnes précisée dans la liste.
S'il n'y a pas de liste, le trigger est déclenché pour toute
instruction UPDATE portant sur la table.
PL/SQL et Triggers
Définition du trigger
62
La définition du trigger précise la table associée au trigger :
une et une seule table
pas une vue.
PL/SQL et Triggers
Types de triggers
63
Le type d’un trigger détermine :
quand ORACLE déclenche le trigger,
combien de fois ORACLE déclenche le trigger.
Le type du trigger est défini par l’utilisation de l’une ou
l’autre des options suivantes :
BEFORE, AFTER, FOR EACH ROW
PL/SQL et Triggers
ORACLE propose deux types de triggers
64
les triggers lignes qui se déclenchent individuellement
pour chaque ligne de la table affectée par le trigger,
les triggers globaux qui sont déclenchés une seule fois.
Si l'option FOR EACH ROW est spécifiée, c'est un
trigger ligne, sinon c'est un trigger global.
PL/SQL et Triggers
Types de triggers
65
Pour les triggers lignes, on peut introduire une restriction
sur les lignes à l'aide d'une expression logique SQL : c'est
la clause WHEN :
Cette expression est évaluée pour chaque ligne affectée par le
trigger.
Le trigger n'est déclenché sur une ligne que si l'expression
WHEN est vérifiée pour cette ligne.
L'expression logique ne peut pas contenir une sous-question.
Par exemple, WHEN (new.empno>0) empêchera l'exécution
du trigger si la nouvelle valeur de EMPNO est 0, négative ou
NULL.
PL/SQL et Triggers
Triggers
66
Le corps du trigger est un bloc PL/SQL :
Il peut contenir du SQL et du PL/SQL.
Il est exécuté si l'instruction de déclenchement se produit et si
la clause de restriction WHEN, le cas échéant, est évaluée à
vrai.
Il est différent pour un trigger ligne et pour un trigger global.
PL/SQL et Triggers
Les noms de corrélation
67
Dans un trigger ligne, on doit pouvoir accéder aux ancienne
et nouvelle valeurs de colonne de la ligne.
Les noms de corrélation permettent de désigner ces deux
valeurs : un nom pour l'ancienne et un pour la nouvelle.
Si l'instruction de déclenchement du trigger est INSERT,
seule la nouvelle valeur a un sens.
Si l'instruction de déclenchement du trigger est DELETE,
seule l'ancienne valeur a un sens.
PL/SQL et Triggers
Les noms de corrélation
68
La nouvelle valeur est appelée
:new.colonne
L'ancienne valeur est appelée
:old.colonne
Exemple : IF :new.salaire < :old.salaire ........
PL/SQL et Triggers
L’option REFERENCING
69
Si une table s'appelle NEW ou OLD, on peut utiliser REFERENCING pour éviter l'ambiguïté entre le nom de la table et le nom de corrélation.
Exemple :
CREATE TRIGGER nomtrigger
BEFORE UPDATE ON new
REFERENCING new AS newnew
FOR EACH ROW
BEGIN
:newnew.colon1:= TO_CHAR(:newnew.colon2);
END;
PL/SQL et Triggers
Les prédicats conditionnels INSERTING,
DELETING et UPDATING
70
Quand un trigger comporte plusieurs instructions de
déclenchement (par exemple INSERT OR DELETE OR
UPDATE), on peut utiliser des prédicats conditionnels
(INSERTING, DELETING et UPDATING) pour
exécuter des blocs de code spécifiques pour chaque
instruction de déclenchement.
PL/SQL et Triggers
Les prédicats conditionnels INSERTING,
DELETING et UPDATING
71
Exemple :
CREATE TRIGGER ...
BEFORE INSERT OR UPDATE ON employe
.......
BEGIN
......
IF INSERTING THEN ....... END IF;
IF UPDATING THEN ........ END IF;
......
END;
PL/SQL et Triggers
Les prédicats conditionnels INSERTING,
DELETING et UPDATING
72
UPDATING peut être suivi d'un nom de colonne :
CREATE TRIGGER ...
BEFORE UPDATE OF salaire, commission ON employe
.......
BEGIN
......
IF UPDATING ('salaire') THEN ........ END IF;
......
END;
PL/SQL et Triggers
Instructions SQL autorisées
73
les instructions du LMD sont autorisées
les instructions du LDD ne sont pas autorisées
les instructions de contrôle de transaction
(ROLLBACK, COMMIT) ne sont pas autorisées.
PL/SQL et Triggers
Triggers
74
Ordre de traitement des lignes
On ne peut pas gérer l'ordre des lignes traitées par une
instruction SQL.
On ne peut donc pas créer un trigger qui dépende de l'ordre
dans lequel les lignes sont traitées.
Triggers en cascade
Un trigger peut provoquer le déclenchement d'un autre trigger.
ORACLE autorise jusqu'à 32 triggers en cascade à un moment
donné.
PL/SQL et Triggers
Triggers
75
Conditions nécessaires pour créer un trigger
il faut avoir le privilège CREATE TRIGGER
il faut soit posséder la table sur laquelle on veut définir un
trigger, soit posséder le privilège ALTER sur la table sur
laquelle on veut définir le trigger, soit posséder le privilège
ALTER ANY TABLE
Modification de triggers
Pour modifier un trigger, on refait une instruction CREATE
TRIGGER suivie de OR REPLACE ou bien on supprime le
trigger (DROP TRIGGER nomtrigger) et on le crée à
nouveau.
PL/SQL et Triggers
Activation d’un trigger
76
Un trigger peut être activé ou désactivé.
S’il est désactivé, ORACLE le stocke mais l’ignore.
On peut désactiver un trigger si :
il référence un objet non disponible
on veut charger rapidement un volume de données important
ou recharger des données déjà contrôlées.
Par défaut, un trigger est activé dès sa création.
PL/SQL et Triggers
Activation d’un trigger
77
Pour désactiver un trigger, on utilise l’instruction ALTER
TRIGGER avec l’option DISABLE :
ALTER TRIGGER nomtrigger DISABLE;
On peut désactiver tous les triggers associés à une table
avec la commande :
ALTER TABLE nomtable DISABLE ALL TRIGGERS;
A l’inverse on peut réactiver un trigger :
ALTER TRIGGER nomtrigger ENABLE;
ou tous les triggers associés à une table :
ALTER TABLE nomtable ENABLE ALL TRIGGERS;
PL/SQL et Triggers
Recherche d’information sur les triggers
78
Les définitions des triggers sont stockées dans les tables
de la métabase, notamment dans les tables
USER_TRIGGERS, ALL_TRIGGERS et DBA_TRIGGERS
PL/SQL et Triggers
La procédure raise_application_error
79
La procédure raise_application_error
( error_number, error_message )
error_number doit être un entier compris entre -20000 et -
20999
error_message doit être une chaîne de 500 caractères
maximum.
Quand cette procédure est appelée, elle termine le trigger,
défait la transaction (ROLLBACK), renvoie un numéro d'erreur
défini par l'utilisateur et un message à l'application.
PL/SQL et Triggers
Gestion des exceptions
80
Si une erreur se produit pendant l'exécution d'un trigger,
toutes les mises à jour produites par le trigger ainsi que
par l'instruction qui l'a déclenché sont défaites.
On peut introduire des exceptions en provoquant des
erreurs.
Une exception est une erreur générée dans une procédure
PL/SQL.
Elle peut être prédéfinie ou définie par l'utilisateur.
Un bloc PL/SQL peut contenir un bloc EXCEPTION gérant les
différentes erreurs possibles avec des clauses WHEN.
Une clause WHEN OTHERS THEN ROLLBACK; gère le cas
des erreurs non prévues.
PL/SQL et Triggers
Exceptions prédéfinies – quelques exemples
81
NO_DATA_FOUND
cette exception est générée quand un SELECT INTO ne retourne
pas de lignes
DUP_VAL_ON_INDEX
tentative d'insertion d'une ligne avec une valeur déjà existante pour
une colonne à index unique
ZERO_DIVIDE
division par zéro
etc
PL/SQL et Triggers
Quelques exemples
82
employe(numserv,....)
service(numserv,...)
/* vérifier que le service de l'employé existe bien */
CREATE TRIGGER verif_service
BEFORE INSERT OR UPDATE OF numserv ON employe
FOR EACH ROW WHEN (new.numserv is not null)
DECLARE
noserv integer;
BEGIN
noserv:=0;
SELECT numserv
INTO noserv
FROM SERVICE
WHERE numserv=:new.numserv;
IF (noserv=0)
PL/SQL et Triggers
Quelques exemples (suite)
83
THEN raise_application_error(-20501, 'N° de service non
correct');
END IF;
END;
employe(salaire,....)
/* mettre une valeur par défaut si le champ ne contient rien */
/* affecter 240 au salaire d'un employe qui n'en a pas */
CREATE TRIGGER smic
BEFORE INSERT OR UPDATE OF salaire ON employe
FOR EACH ROW WHEN (new.salaire is null)
BEGIN
SELECT 240
INTO :new.salaire
FROM employe;
END;
PL/SQL et Triggers
Quelques exemples
84
employe(numemp,salaire,grade,...)
grille(grade,salmin,salmax)
/* vérifier le salaire d'un employé */
/* s'assurer que le salaire est compris dans les bornes correspondant au grade de l'employé */
CREATE TRIGGER verif_grade_salaire
BEFORE INSERT OR UPDATE OF salaire, grade ON employe
FOR EACH ROW
DECLARE
minsal number;
maxsal number;
BEGIN
/* retrouver le salaire minimum et maximum du grade */
SELECT salmin,salmax
INTO minsal, maxsal
FROM grille
PL/SQL et Triggers
Quelques exemples (suite)
85
WHERE grade= :new.grade;
/* s'il y a un problème, on provoque une erreur */
IF (:new.salaire<minsal OR :new.salaire>maxsal)
THEN
raise_application_error (-20300,'Salaire‘||TO_CHAR
(:new.salaire)||'incorrect pour ce grade');
EXCEPTION
WHEN no_data_found THEN
raise_application_error(-20301,'Grade incorrect');
END;
PL/SQL et Triggers