ETUDE DU LANGAGE PL/SQL

LES PROCEDURES ET FONCTIONS STOCKEES

LES TRIGGERS

 

 

1.                      ETUDE DU LANGAGE PL/SQL

 

1.1. Introduction

 

 

Sql est un langage complet pour travailler sur une base de données, mais il ne comporte pas d'instructions procédurales.

 

 

PL/SQL comprend quant à lui :

 

· la partie LMD de SQL (Select, Update, Insert, Delete),

 

· la gestion des transactions (Commit, Rollback ...),

 

· les fonctions de manipulation telles MONTH, YEAR …,

 

· plus une partie procédurale (affectation, calculs, IF, WHILE, ...),

 

PL/SQL va en particulier nous permettre de créer de nouveaux objets dans la base de données : : procédures et fonctions ainsi que triggers (‘déclencheurs’). Ces objets sont des unités de traitements :

-          les procédures et fonctions stockées permettent d’effectuer certains traitements lourds ou confidentiels sur le serveur ; elles permettent aussi de factoriser les traitements dans les architectures client/serveur (plusieurs clients utilisent la même procédure).

-          les triggers permettent de maintenir dynamiquement la cohérence de la base de données et de décharger les programmes de cette tâche ; exemple : la mise à jour d’une table déclenche automatiquement une mise à jour sur une autre table.

 

De plus, nous verrons que ces traitements stockés dans la base de données permettent d’alléger le trafic sur le réseau.

 

 


 

1.2. Structure d'un bloc Pl/SQL

 

 

La structure d'un bloc est la suivante :

 

BEGIN
            DECLARE …
            Instructions SQL et PL/SQL;
            Peut éventuellement contenir un autre bloc Pl/Sql                                                    

 
END |

 

 

Remarque :

Chaque instruction PL/SQL ou SQL de n'importe quelle section doit se terminer par un ';'.

 

La structuration des instructions en blocs procure une plus grande lisibilité des traitements.

 

Exemple de bloc PL/SQL :

 

 DELIMITER |;
 DECLARE  code_prod  int;
 DECLARE
 qte_stock  int;

    
Select quantite, codeprod

  into qte_stock, code_prod

  from inventaire
            where produit='raquette tennis';
            --  contrôle du stock suffisant --
            If qte_stock > 0
     then

              update inventaire

              set quantite=quantite-1
                        where produit='raquette tennis';
                        insert into achat
                        values (code_prod, CURRENT_DATE);
            end if;
 
 END |


 

Les déclarations PL/SQL

 

La partie déclarative dans un bloc PL/SQL, peut comporter les trois types de déclarations suivants.

·      déclaration des variables et des constantes,

·      déclaration de curseurs,

·      déclaration des exceptions. (non traité ici)

 

 

1.3.     L'affectation des variables PL/SQL

 

 

1.3.1. Principaux types de données

 

Chaque variable ou constante utilisée dans un bloc PL/SQL, possède un type de données qui détermine son format de stockage et sa plage de valeurs valides.

 

Les types de données offerts par PL/SQL sont d'abord les types offerts pour les colonnes des tables MySql auxquels s'ajoutent d'autres types tel le type boolean.

 

 

1.3.2. Syntaxe de déclaration des variables et constantes

 

Une constante est définie comme une variable sauf qu’on y ajoute le mot-clé CONSTANT, le contenu est alors non modifiable.

 

Les variables et constantes sont précédées du mot DECLARE et utilise la syntaxe suivante :

 

Nomdonnée  [CONSTANT]  nomtype

 

Remarque :

·      L'attribut constant permet de figer l'affectation.

 

Deux possibilités d'affectation sont disponibles :

 

L'initialisation d'une variable se fait de la façon suivante : SET nomvariable = valeur ;

Exemple : SET A = A + 1 ;

L'initialisation peut également se faire par la clause INTO d'une requête SQL :

SELECT nomcli FROM client

INTO nom

WHERE numcli = 104 ;

 

L'affectation par la clause INTO s'effectue sous certaines conditions.

Si le Select retourne une et une seule ligne, l'affectation s'effectue correctement.

 

Par contre,

. Si le Select retourne 0 ligne : è une erreur PL/SQL est générée.

. Si le Select retourne plusieurs lignes : è une erreur PL/SQL est générée.


 

Remarque :      . Entre BEGIN et END, les instructions select ne servent qu'à alimenter des variables, elles ne provoquent aucun affichage à l'écran. Si le bloc d'instructions a pour but d'afficher un résultat à l'utilisateur, il faudra insérer le résultat dans une table temporaire à l'intérieur du bloc et faire un select de la table résultat à l'extérieur du bloc. La table temporaire (nommée resultat dans l'exemple) devra être créée avant l'exécution du bloc.

 

Exemple

On va utiliser la table emp :   Emp(empno, ename, job, mgr, hiredate, sal , comm, #deptno)

 

DELIMITER |;

BEGIN

DECLARE  vjob  varchar(15);
DECLARE  vnom varchar(30);
DECLARE  message varchar(50);

select job

into vjob

from emp

where ename='MARTIN';

            --  Traitement selon le job et alimentation d'un champ message pour savoir ce qui        a été effectué :

. . .
            insert into resultat

values (message);
 END |

 

 

 

1.4. Les structures conditionnelles

 

1.4.1. L'instruction   IF … THEN … END IF

 

IF THEN

IF condition

THEN                     

   instruction ou séquence d'instructions;

END IF;

 

Remarque : le then peut être placé à côté du if.

Il faut préciser que les instructions peuvent être écrites sur 1 ou plusieurs lignes, on peut même écrire plusieurs instructions sur une même ligne, le principal étant de placer un point-virgule à la fin de chaque instruction.

 

IF THEN ELSE

IF condition

THEN

   instruction ou séquence d'instructions;

ELSE

   instruction ou séquence d'instructions;

END IF;

 

 

Remarques :

. Il est possible d'imbriquer les IF.

. La condition peut utiliser des variables ainsi que les opérateurs suivants : =, <, >, <=, >=, <>, IS NULL, IS NOT NULL.

 

IF condition1

THEN

     statement1;

ELSE                             

     IF condition2

     THEN        

           statement2;          

     ELSE                        

           IF condition3

           THEN   

               statement3;     

           END IF;            

     END IF;                  

END IF;                       

 

 DELIMITER |;

 BEGIN

 DECLARE  vjob varchar(15);
 DECLARE  vnom varchar(40);
 DECLARE  message varchar(100);
 SET  vnom = 'MARTIN';
 Select job

 into vjob

 from emp

 where ename=vnom;
 --  traitement selon le job
 
If vjob is NULL
 then

            SET message = vnom || ' est sans travail';
 else

            if vjob = 'SALESMAN'

            then

                        update emp

            set comm=1000

            where ename=vnom;
                        SET message = vnom , ' a 1000 Frs de commission';
            else
                        update emp

            set comm=0

            where ename=vnom;
                        SET message = vnom , ' n''a pas de commission ';
            end if;

 end if;
 insert into resultat values (message);
 END |


 

1.4.2. L'instruction CASE

 

Cette syntaxe, qui diffère du CASE normal , va permettre d' effectuer une action si une condition est  vérifiée.

Il existe deux types de syntaxes  :  la première se rapprochant de l'utilisation du 'SWITCH' dans les langages de programmation, et

l'autre étant équivalente à une succession de 'IF ... ELSE IF ... ELSE IF ... ELSE  ...'  .

Exemple Syntaxe1 :

CASE var

WHEN 1 THEN SELECT 'Je suis 1';

WHEN 2 THEN SELECT 'Je suis 2';

ELSE SELECT 'Je suis autre chose que 1 et 2';

END CASE;

END |

Dans ce cas , la variable 'var' est comparée à chaque cas rencontré, et si aucune des valeurs n'est vérifiée dans les WHEN, alors

l'instruction après ELSE sera exécutée.

 

Exemple Syntaxe2 :

BEGIN

CASE

WHEN var = 1 THEN SELECT 'Je suis 1';

WHEN var = 2 THEN SELECT 'Je suis 2';

ELSE SELECT 'Je suis autre chose que 1 et 2';

END CASE;

END |

Dans ce cas , la variable 'var'  n'est pas évaluée ; au lieu de cela, nous passons d' un bloc de WHEN à l'autre en comparant si une expression est vraie. Si c'est le cas, nous exécutons alors l'instruction qui la suit, sinon, si aucune des expressions n'est vérifiée, alors l'instruction du ELSE est effectuée.

 


 

1.5. Les structures itératives

 

PL/SQL nous offre la possibilité d'effectuer des traitements itératifs grâce à 3 types d'instructions : LOOP, REPEAT et WHILE.

 

1.5.1. L'instruction LOOP

 

C'est une structure de boucle qui répète un bloc d'instructions tant qu'elle ne rencontre pas une instruction LEAVE pour l'arrêter.

Exemple :

CREATE PROCEDURE loop1()

BEGIN

DECLARE i INT DEFAULT 0;

LOOP

            SET i := i + 1;

            SELECT i;

END LOOP;

END |

Aucune condition d'arrêt n'a été rencontrée, et une erreur ne sera rencontrée que lorsque la valeur maximale val i de INT sera rencontrée, soit le chiffre : 2 147 483 647.

Il est possible d'arrêter brusquement la boucle à l'aide d'une instruction du type : LEAVE nom_label

Exemple d'arrêt lorsqu'un label est présent :

CREATE PROCEDURE loop1()

BEGIN

DECLARE i INT DEFAULT 0;

je_suis_un_label: LOOP

            SET i := i + 1;

            SELECT i;

            IF i = 10 THEN

            LEAVE je_suis_un_label;

            END IF;

END LOOP je_suis_un_label;

END |

Le code s'exécute, et si i vaut 10, alors la boucle est arrêtée grâce au nom du label.

Le label indiqué avant l'instruction de boucle doit être le même que celui qui la termine.

 

1.5.2. L'instruction REPEAT

 

Ce type de boucle permet de répéter un bloc d'instructions jusqu'à ce qu'une condition soit vérifiée.

Exemple :

CREATE PROCEDURE repeat1()

BEGIN

DECLARE i INT DEFAULT 0;

REPEAT

            SET i := i + 1;

            SELECT i;

UNTIL i = 10 END REPEAT;

END |

Une boucle est lancée jusqu'à ce que la valeur de variable locale i soit égale à 10.

Plus court que la version avec LOOP pour un résultat identique.

Les labels sont supportés de la même manière qu'avec LOOP et prennent donc la même syntaxe.


 

1.5.3. L'instruction WHILE

 

C'est une structure de type boucle qui répète un bloc d'instructions tant qu'une condition est vraie.

Exemple :

CREATE PROCEDURE while1()

BEGIN

DECLARE i INT DEFAULT 0;

WHILE i < 10 DO

            SET i := i + 1;

            SELECT i;

END WHILE;

END |

Tant que la variable locale i est inférieure à 10, le bloc d'instructions est exécuté.

 

 

1.5.4. L'instruction ITERATE

 

ITERATE ne peut être utilisée qu'à l'intérieur d'une boucle LOOP, REPEAT ou WHILE et signifie : "exécute encore une fois la boucle".

Exemple avec LOOP :

CREATE PROCEDURE loop1()

BEGIN

DECLARE i INT DEFAULT 0;

je_suis_un_label: LOOP

            SET i := i + 1;

            SELECT i;

            IF i < 10 THEN ITERATE je_suis_un_label;

            END IF;

            SELECT 'Je suis ', i;

            LEAVE je_suis_un_label;

END LOOP je_suis_un_label;

END |

La boucle se lance, fait ses instructions , arrive sur la condition qui vérifie que la variable locale i est inférieure à 10 ; Si c'est le cas, la boucle est relancée.

 

Exemple avec REPEAT :

CREATE PROCEDURE repeat1()

BEGIN

DECLARE i INT DEFAULT 0;

je_suis_un_label: REPEAT

            SET i := i + 1;

            SELECT i;

            IF i < 10 THEN ITERATE je_suis_un_label;

            END IF;

            SELECT 'Je suis ', i;

UNTIL i < 20 END REPEAT je_suis_un_label;

END |


 

Exemple avec WHILE :

CREATE PROCEDURE while1()

BEGIN

DECLARE i INT DEFAULT 0;

je_suis_un_label: WHILE i < 10 DO

            SET i := i + 1;

            SELECT i;

            IF i < 10 THEN ITERATE je_suis_un_label;

            END IF;

            SELECT 'Je suis ', i;

END WHILE je_suis_un_label;

END|

 


 

Préambule : La validation, l’annulation et la notion de transaction

 

Nous avons vu que par défaut, toute erreur non interceptée ainsi que toute erreur interceptée pour laquelle le bloc d’exception contient raise_application_error provoquent l’annulation de toutes les mises à jour (au sens large). Dans les autres cas, les mises à jour sont validées (c’est à dire enregistrées).

 

Il est possible de demander explicitement la validation  des mises à jour à n’importe quel(s) endroit(s) d’un bloc Pl/Sql, il suffit pour cela de placer l’instruction commit ; à l’endroit (ou aux endroits) souhaité (s).

 

Toute erreur non interceptée ou toute erreur interceptée et renvoyée avec raise_application_error provoquera alors uniquement l’annulation des mises à jour effectuées depuis le dernier commit.

 

Pour demander explicitement l’annulation des mises à jour à n’importe quel endroit du bloc, il faut placer l’instruction rollback ;

 

Quand l’exécution d’un bloc Pl/Sql démarre, démarre alors une transaction (il y a une instructionimplicite de démarrage de transaction) et quand l’exécution du bloc prend fin, il y a une instruction implicite de fin de transaction.

Une transaction est un ensemble indivisible d’opérationsc’est à dire que l’ensemble des opérations sera validé ou annulé.

 

Par défaut, MySql considère tout le bloc comme une seule transaction car s’il y a une erreur non interceptée ou bien une erreur interceptée et renvoyée, l’ensemble des opérations est annulé sinon l’ensemble des opérations est validé.

 

Le développeur peut faire plusieurs transactions à l’intérieur du bloc, en effet s’il place un commit ou un rollback dans le bloc, cela met fin à la transaction en cours et une autre transaction démarre.

 

Cette notion de transaction est très importante (par exemple pour garantir le débit/crédit lors d’opérations sur des comptes).

 


 

2.           LES PROCEDURES ET FONCTIONS STOCKEES

 

 

2.1. Définition et utilisation

 

 

Les procédures ou fonctions stockées sont des blocs PL/SQL nommés que l'on définit et stocke une seule fois dans la base.

 

Les procédures ou fonctions stockées peuvent être paramétrées.

 

La notion de procédure ou fonction stockée a été conçue dans l'esprit de grouper un ensemble de commandes SQL avec des instructions procédurales, pour constituer une unité de traitement pouvant être appelée à partir de n'importe quel programme ou directement sous MySql.

 

 

Intérêts d’une procédure ou fonction stockée au niveau du développement :

-          une procédure ou fonction stockée peut être appelée par plusieurs applications et elle reste indépendante de la partie appelante :

ð      augmentation de la productivité lors de l’écriture des applications,

ð      la recompilation d’une procédure ou fonction n’exige pas la recompilation de l’ensemble du code de l’application.

 

 

Intérêts d’une procédure lors de l’exécution de traitements :

-          réduction du trafic sur le réseau (le client envoie le nom de la procédure ou fonction à exécuter au lieu d'envoyer tout le texte d'une commande SQL, ceci sera revu dans le cours sur le client-serveur de traitements),

-          une procédure ou fonction est compilée lors de son stockage dans la base : à l’exécution, elle n'a plus à être compilée.

ð      gain de temps.

 

 

Intérêts d’une procédure ou fonction au niveau de la sécurité :

-          une procédure ou fonction est un objet de la base appartenant à un utilisateur : les mécanismes de sécurité et de confidentialité fonctionnent (GRANT et REVOKE),

-          l’accès à certaines tables peut n’être autorisé qu’au travers des procédures et fonctions : un utilisateur peut disposer d’autorisations d’exécution sur une procédure ou fonction sans disposer d’autorisation sur les tables manipulées par la procédure ou fonction è on peut faire l'analogie avec les vues excepté qu'une vue est construite forcément sur un SELECT.

 


 

2.2. Les procédures stockées

 

 

·        Ecriture d'une procédure stockée

 

Version MySql :

CREATE PROCEDURE nomprocedure  [ (paramètres)]
  -- bloc PL/Sql
  BEGIN
            [Déclaration des variables locales;]
            Instructions SQL et PL/Sql;
  END [nomprocedure];

 

 

Remarques :

 

·      Chaque paramètre est défini selon la syntaxe suivante :
nomparametre  [IN | OUT | IN OUT]  type
IN : indique que le paramètre est passé en entrée (c'est le statut par défaut),
OUT : indique que le paramètre est renseigné par la procédure,
IN OUT : indique que le paramètre est en entrée-sortie.

 

·      Le corps de la procédure commence par Begin et se termine par le mot-clé END suivi éventuellement par le nom de la procédure.

Le corps d'une procédure comporte trois parties :

- une partie déclarative qui est facultative,

- une partie exécutable,

- une partie optionnelle pour la gestion des erreurs.

 

·      La partie déclarative contient la déclaration des variables locales. Le mot-clé DECLARE est obligatoire devant chaque variable.

 

·      La partie exécutable doit au moins comporter une instruction.


 

Exemple : Augmentation du salaire de l'employé dont le n° est transmis, le montant à ajouter est également transmis

 

Version MySql :

CREATE PROCEDURE AugmenterSalaire(IN NumSal double, montant double)

BEGIN

     DECLARE SalaireActuel double;

     Select sal

     into SalaireActuel

     From emp

     Where empo = NumSal;

     Update emp

     set sal = sal + montant

     Where empo = NumSal;

END |

 

Il n'y a aucun standard pour l'écriture des procédures stockées en pseudo-code. On peut proposer l'algorithme suivant pour la procédure ci-dessus :

PROCEDURE AugmenterSalaire (données : NumSal : entier, montant : réel)

     SalaireActuel : réel

     SalaireNull : Exception

DEBUT

     Select sal

                        into SalaireActuel

                        From emp

     Where empno = NumSal

     SI SalaireActuel = NULL

     ALORS déclencher exception SalaireNull

     SINON

                Update emp

                set sal = sal + montant

                Where empno = NumSal

     FSI

EXCEPTION

     SUIVANT exception

                                   NonTrouvé :

                            Envoyer l'erreur 'Employé inconnu'

                 SalaireNull :

                            Envoyer l'erreur 'Salaire non renseigné'

     FSUIVANT

FIN

 

 

·        Création ou remplacement d'une procédure stockée

 

En MySql, la création de la procédure peut se faire sous l'onglet Sql. Il faut penser à changer le délimitateur qui est ; par défaut. Mettre par exemple |.

 


 

·        Mise au point d'une procédure stockée

 

Un message est affiché en cas d'erreur. Sinon le message "procédure créée…" est affiché.

 

·        Appel d'une procédure stockée

 

Ex. : CALL AugmenterSalaire(7369, 200);

 

. Dans un bloc pl/sql ou dans une autre procédure ou fonction stockée :

Ex. :

. Avec des constantes en paramètres :

BEGIN

CALL AugmenterSalaire(7369,10.10);

           

END;

 

. Dans un programme hôte :

 

Non étudié ici.

 

 

·     Suppression d'une procédure stockée

 

La suppression est assurée par la commande suivante :

 


 DROP PROCEDURE nomprocedure;

 

 

2.3. Les fonctions stockées

 

 

La structure d'une fonction est identique à celle d'une procédure, mais les fonctions possèdent une clause RETURNS type en "entête" et au moins une clause RETURN(valeur).

Tout ce qui a été dit concernant les droits pour une procédure stockée est également valable pour les fonctions stockées.

 

·       Ecriture d'une fonction stockée

 

CREATE [OR REPLACE] FUNCTION nomfonction [ (paramètres)]
 RETURNS type
[DETERMINISTIC]
 BEGIN
                        [Déclarations de variables locales;]
                        Instructions SQL et PL/Sql;
                        RETURN(Valeur);
 END ;


 

Remarques :

 

Chaque paramètre est défini selon la syntaxe suivante : nomparametre  [IN | OUT | IN OUT]  type

Il est possible de placer plusieurs return(valeur) dans le corps de la fonction. Un return(valeur) provoque le retour immédiat à l'appelant avec une valeur de retour.

 

Exemple : Calcul du nombre moyen d'années d'ancienneté pour les employés exerçant le job transmis en paramètre

 

DELIMITER |

CREATE FUNCTION MoyenneAnc  (jobsai VARCHAR(30))  RETURNS float

DETERMINISTIC

BEGIN

                DECLARE ancmoyen float;

                select avg(YEAR(curdate()) - YEAR(hiredate))

                into ancmoyen

                from emp

                where job = jobsai;

                RETURN (ancmoyen);

END |

 

 

Il n'y a aucun standard pour l'écriture des fonctions stockées en pseudo-code. On peut proposer l'algorithme suivant pour la fonction ci-dessus :

 

FONCTION  MoyenneAnc (donnée : jobsai : chaîne de caractères) : réel

ancmoyen : réel

DEBUT

                select avg(YEAR(curdate()) - YEAR(hiredate))

                                   into ancmoyen

                                   from emp

                                   where job = jobsai

                retourner (ancmoyen)

FIN

 


 

·        Création ou remplacement d'une fonction stockée

 

Idem procédure stockée.

 

·        Mise au point d'une fonction stockée

 

Idem procédure stockée.

 

·          Appel à une fonction stockée

 

SOUS MYSQL  :  SELECT MoyenneAnc('CLERK');

 

·        Suppression d'une fonction stockée

 

La suppression est assurée par la commande suivante :

 


 DROP  FUNCTION  nomfonction ;


 

3.                      LES TRIGGERS (OU DECLENCHEURS)

 

3.1. Définition

 

*     Un trigger base de données est un ensemble de traitements PL/Sql.

*     Un trigger base de données est déclenché automatiquement par un ou plusieurs événements prédéfinis,
il ne peut donc pas être appelé directement.

*     Un trigger base de données est attaché à une et une seule table.

*     Si une table est supprimée, les triggers base de données qui lui sont associés sont automatiquement supprimés.

 

 

Un trigger base de données est identifié par cinq caractéristiques :

1.    Un séquencement,

BEFORE ou AFTER : on précise si le trigger se déclenche avant ou après l'événement.

Les triggers BEFORE sont généralement utilisés pour faire des contrôles.

Les triggers AFTER sont généralement utilisés pour faire des mises à jour consécutives à l’ordre SQL déclencheur.

2.    Un événement qui le déclenche,

INSERT, UPDATE, DELETE : cet événement concerne une et une seule table, celle-ci devra être

précisée.

3.     Un type,

par LIGNE : accès aux informations de la ligne ayant déclenché le trigger et vérification des valeurs par rapport aux autres lignes de la table.

4.    Les ordres du traitement (bloc pl/sql).

 

Les combinaisons possibles sont les suivantes :

 

Séquencement

Evénement

BEFORE

INSERT

 

UPDATE

 

DELETE

AFTER

INSERT

 

UPDATE

 

DELETE

 


 

3.2. Ecriture d'un trigger

 

 


 CREATE OR REPLACE TRIGGER  nomtrigger

  Séquencement (before ou after)

  Evénement (insert, update ou delete)

  ON nom de la table

 FOR EACH ROW

 BEGIN

        ordres du traitement;

 END  [nomtrigger];

 

Remarques :

 

q       UPDATE OF nomcolonne On nomtable : permet d'indiquer que le trigger est déclenché uniquement en cas de modification de la colonne stipulée.

 

q       Type : le type par défaut est par ordre. Il faudra donc préciser le type uniquement si on souhaite la vérification au niveau ligne (ce qui est le cas le plus fréquent), pour cela, il faudra écrire : FOR EACH ROW.

 

q       Le bloc pl/sql ne peut pas contenir d'instructions pour gérer les transactions (Commit, Rollback).

 

 

Référencement des valeurs des colonnes :

 

Pour référencer l'ancienne et/ou la nouvelle valeur d'une colonne, on utilise deux variables prédéfinies OLD et NEW.

 

 

OLD

NEW

INSERT

NULL

nouvelle valeur

UPDATE

ancienne valeur

nouvelle valeur

DELETE

ancienne valeur

NULL

 

L'accès à une colonne de :new et de :old s’écrit respectivement :

new.nomcolonne 

old.nomcolonne

 


 

Exemples :

 

Si on a l'ordre insert suivant :

insert into dept

values (90, 'Informatique', 'Immeuble A');

Dans le trigger correspondant à l'insertion dans la table dept, new.deptno vaudra 90, new.dname vaudra Informatique et new.loc vaudra Immeuble A.

 

Si on a l'ordre update suivant :

update dept

set loc = 'Immeuble B'

where deptno=90;

Dans le trigger correspondant à la modification dans la table dept, new.deptno vaudra 90, new.dname vaudra Informatique et new.loc vaudra Immeuble B.  old.deptno vaudra 90, old.dname vaudra Informatique et old.loc vaudra Immeuble A.

 

Si on a l'ordre delete suivant :

delete dept

where deptno=90;

Dans le trigger correspondant à la suppression dans la table dept, old.deptno vaudra 90, old.dname vaudra Informatique et old.loc vaudra Immeuble B.

 

Déclenchement d’erreurs :

 

Le trigger permet de vérifier la cohérence d’une instruction SQL de mise à jour : Insert, Update ou Delete. Il est souvent nécessaire de provoquer une erreur dans le trigger pour empêcher cette mise à jour.

La commande permettant de déclencher une erreur personnalisée est de type :

signal sqlstate "25000" set message_text ="Votre message d'erreur""

 

"25000" est un exemple de numéro d'erreur. Il faut juste choisir un nombre supérieur à 20000.


Exemple : trigger pour refuser l’insertion d’un employé si sa commission ajoutée au total des commissions dépasse le total autorisé :

 

-- Suppression du trigger ctrlcomm si celui-ci existe

DROP TRIGGER IF EXISTS ctrlcomm;

 

DELIMITER  |

-- Création du trigger

CREATE TRIGGER ctrlcomm BEFORE INSERT

ON emp FOR EACH ROW

BEGIN

            DECLARE totcomm float;

 

            SELECT sum(comm)

            INTO totcomm

            FROM emp;

 

            If (totcomm + new.comm) > 20000 then

                        signal sqlstate "32000" set message_text ="Erreur-Commission trop importante"

            end if;

end |

DELIMITER ;

 

Il n'y a aucun standard pour l'écriture des triggers en pseudo-code. On peut proposer l'algorithme suivant pour le trigger ci-dessus :

 

TRIGGER ctrlcomm

Déclenchement : avant insertion dans table emp

Type trigger : niveau ligne

totcomm : réel

tot : exception

 

DEBUT

            select sum(comm)

            into totcomm

            from emp

            SI totcomm + :new.comm > 20000

            ALORS

                        Déclencher exception tot

            FSI

 

EXCEPTION

SI exception = tot

ALORS

       Envoyer l'erreur "Erreur-Commission trop importante"

            FSI

FIN


 

Remarque

Sur MySql, contrairement à Oracle par exemple, un trigger base de données ne peut s'exécuter à la fois en INSERT et/ou en UPDATE et/ou en DELETE

 

 

3.3 Création ou remplacement d'un trigger

 

La création ou le remplacement d'un trigger dans la base s'effectue sous l'onglet SQL. Le trigger (ou déclencheur) est associé à une table. Sur les versions  récentes de PhpMyAdmin l'onglet <Déclencheur> propose une interface graphique pour créer ou modifier les triggers.

 

 

 

3.4. Suppression d’un trigger

 


 DROP TRIGGER nomtrigger ;

 

 

 

3.5. Avantages de l'utilisation des triggers

 

·      Implémentation des contraintes sémantiques et donc refus des mises à jour (au sens large) incohérentes,

·      Implémentation de règles de validation et de sécurité complexes (on peut par exemple contrôler la date et l'heure de l'opération effectuée),

·      Réaction aux instructions UPDATE, DELETE, INSERT ce qui permet d'enclencher un traitement suite à l'une de ces actions,

·      Maintenance de plusieurs tables "miroir" sur différents sites d'un réseau : on assure ainsi le fait que toutes les modifications soient répercutées sur tous les sites en même temps,

*     Augmentation de la productivité de développement car le code du trigger est écrit une seule fois au lieu d'être écrit dans chaque programme applicatif voulant effectuer les contrôles nécessaires,

*     Constitution d'audits personnalisés.

 

 


 

3.6. Différences entre triggers et contraintes d'intégrité déclaratives

 

Les triggers et les contraintes de tables peuvent être utilisés tous les deux pour assurer la cohérence de la base de données.

 

Cependant les triggers et les contraintes d'intégrité de tables ne fonctionnent pas tout à fait de la même manière.

 

Une contrainte d'intégrité déclarative (primary key, foreign key, not null, unique …) s'applique à toutes les données et ne pourra être créée si certaines données déjà en place ne la vérifient pas.

 

Les triggers ne vont pas vérifier l'ensemble des données en place lors de leur création. Ils effectuent un traitement seulement lors de leur déclenchement. De ce fait, un trigger ne peut pas garantir que toutes les données présentes dans une table sont conformes aux règles définies par le trigger associé à cette table.

Un trigger permet de gérer la transition des données. Il permet de vérifier une contrainte particulière au moment où une donnée change de valeur.