0% found this document useful (0 votes)
105 views9 pages

Bases de Données MySQL Triggers Corrigé

This document discusses triggers in MySQL. It provides examples of triggers that can be used to: 1. Automatically update a count field in a related table when rows are inserted, updated, or deleted from another table. 2. Format names in a table to uppercase family names and title case first names. 3. Validate data and prevent invalid operations like borrowing a book that is already checked out or borrowing more than 3 books at a time. 4. Automatically set default values like setting the borrow date to the current date or calculating duration fields. The triggers presented cover common operations like inserting, updating, and deleting rows across multiple tables to maintain relational integrity and enforce business rules.

Uploaded by

Rihab BEN LAMINE
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
105 views9 pages

Bases de Données MySQL Triggers Corrigé

This document discusses triggers in MySQL. It provides examples of triggers that can be used to: 1. Automatically update a count field in a related table when rows are inserted, updated, or deleted from another table. 2. Format names in a table to uppercase family names and title case first names. 3. Validate data and prevent invalid operations like borrowing a book that is already checked out or borrowing more than 3 books at a time. 4. Automatically set default values like setting the borrow date to the current date or calculating duration fields. The triggers presented cover common operations like inserting, updating, and deleting rows across multiple tables to maintain relational integrity and enforce business rules.

Uploaded by

Rihab BEN LAMINE
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 9

Bases de données

MySQL – Triggers
Corrigé
Bertrand LIAUDET

1. Les employés triggers

Système de triggers

B insert EMP -
B update EMP -
B delete EMP -
A insert EMP Update Dept set nbEmp++ where ND=new.ND
A update EMP Update Dept set nbEmp - - where ND=old.ND
Update Dept set nbEmp++ where ND=new.ND
A delete EMP Update Dept set nbEmp - - where ND=old.ND

B insert DEPT Set nbEmp=0


B update DEPT Select count(*) from emp Where nd=new.nd into nb;
Set new.nbemp=nb;
B delete DEPT -
A insert DEPT -
A update DEPT -
A delete DEPT -

Code de triggers

Trigger after
drop trigger if exists tai_emp;
# tai : trigger after insert
delimiter //
create trigger tai_emp
after insert on emp
for each row
begin
update dept set nbemp=nbemp+1 where nd=new.nd;
end;
//
delimiter ;
test :
insert into emp values (1, "a", "a", "1980-12-31", 0, NULL, 10, 7902);
select * from dept;

drop trigger if exists tau_emp;


# tai : trigger after update
delimiter //
create trigger tau_emp
after update on emp
for each row
begin
update dept set nbemp=nbemp-1 where nd=old.nd;
update dept set nbemp=nbemp+1 where nd=new.nd;
end;
//
delimiter ;
test :
update emp set nd=20 where ne=1;
select * from dept;

drop trigger if exists tad_emp;


# tai : trigger after delete
delimiter //
create trigger tad_emp
after delete on emp
for each row
begin
update dept set nbemp=nbemp-1 where nd=old.nd;
end;
//
delimiter ;
test :
delete from emp where ne=1;
select * from dept;

Trigger before
drop trigger if exists tbi_dept;
# tbi : trigger before insert
delimiter //
create trigger tbi_dept
before insert on dept
for each row
begin
set new.nbemp = 0;
end;
//
delimiter ;
test :
insert into dept values (50, "a", "b", 5);

drop trigger if exists tbu_dept;


# tbi : trigger before update
delimiter //
create trigger tbu_dept
before update on dept
for each row
begin
declare nb int;
If old.nbEmp != new.nbEmp then
select count(*) from emp Where nd=new.nd into nb;
set new.nbemp = nb;
end if;
end;
//
delimiter ;
test :
update dept set nbemp=1 where nd=50;
1. La bibliothèque - triggers

1) Créer la BD « biblio » à partir du script fourni.


2) On souhaite ajouter l’attribut « emprunté » qui est un booléen et précise si un livre est
actuellement emprunté ou pas. Passez la requête qui permet d’ajouter cet attribut
(ALTER TABLE).
alter table livres add libre integer;

3) Mettre à jour les valeurs de cet attribut (UPDATE).


update livres set libre=1 ;
update livres set libre=0
where nl=any(select nl from emprunter where dateret is null);

4) Ecrire les triggers qui permettent de gérer cet attribut calculé.


drop trigger if exists tai_emprunter;
# tai : trigger after insert
delimiter //
create trigger tia_emprunter
after insert on emprunter
for each row
begin
if new.dateret is null then
update livres set libre=0 where nl=new.nl;
# select new.nl into @vnl; si on veut verifier la valeur de new.nl
end if ;
end;
//
delimiter ;

drop trigger if exists tau_emprunter;


# tau : trigger after update
delimiter //
create trigger tau_emprunter
after update on emprunter
for each row
begin
if new.dateret is not null then
update livres set libre=1 where nl=new.nl;
# select new.nl into @vnl; pour verifier la valeur de new.nl
end if;
end;
//
delimiter ;

REMARQUE :
L’attribut devrait aussi être géré dans la table des livres : à la création et en modification.
Au minimum, on a intérêt à définir une valeur par défaut à la création :
alter table livres modify libre integer default 1 ;

5) On souhaite ajouter l’attribut « dureeEmprunt » qui donne la durée de l’emprunt en


jours après le retour du livre. Ecrire la requête qui permet d’ajouter cet attribut (ALTER
TABLE).
alter table emprunter add dureeEmprunt integer;
6) Mettre à jour les valeurs de cet attribut pour tous les tuples de la table concernée
(UPDATE).
update emprunter set dureeEmprunt = to_days(dateRet)-to_days(dateEmp)
where dateRet is not null;

7) Ecrire le système de triggers qui permet de gérer cet attribut calculé.


drop trigger if exists tbi_emprunter;
# tbi : trigger before insert
delimiter //
create trigger tbi_emprunter
before insert on emprunter
for each row
begin
set new.dureeEmprunt = to_days(new.dateRet)-to_days(new.dateEmp);
end;
//
delimiter ;

drop trigger if exists tbu_emprunter;


# tbu : trigger before update
delimiter //
create trigger tbu_emprunter
before update on emprunter
for each row
begin
set new.dureeEmprunt = to_days(new.dateRet)-to_days(new.dateEmp);
end;
//
delimiter ;
remarques :
On peut se contenter de réaffecter (« setter ») dureeEmprunt dans tous les cas. Si l’une des deux
dates vaut NULL, dureeEmprunt vaudra NULL.

8) On souhaite que la date d’emprunt soit désormais un attribut automatique qui vaut
automatiquement la date du jour de la création du tuple correspondant dans la BD.
Comment faire ça ? Ecrire le code correspondant.

 Solution 1 : attribut timestamp


alter table emprunter modify dureeMax integer not null default 14;
alter table emprunter modify dateEmp timestamp default now();
remarques :
Un attribut de type timestamp est affecté automatiquement aux date et heure de création et de
modification. Il est not null par défaut.
Si on ajoute default now() : il prendra les date et heure de création mais ne sera pas modifié en cas
de modification. Par contre si on remet la valeur de dateEmp à NULL, dateEmp prend la valeur des
date et heure de modification. Si on affecte une valeur à dateEmp, elle est prise en compte.

 Solution 1 : gestion d’un trigger beefore


drop trigger if exists tbi_emprunter;
# tai : trigger after insert
delimiter //
create trigger tbi_emprunter
before insert on emprunter
for each row
begin
set new.dateEmp=current_date();
end;
//
delimiter ;

drop trigger if exists tbu_emprunter;


# tau : trigger after update
delimiter //
create trigger tbu_emprunter
before update on emprunter
for each row
begin
if new.dateEmp != old.dateEmp then
set new.dateEmp= old.dateEmp;
end if;
end;
//
delimiter ;

9) On souhaite que les noms de famille soient en majuscules et les prénom en minuscules avec
seulement la première lettre en majuscule. Ecrire le système de triggers qui permet de
gérer cette demande.
drop trigger if exists tbi_adherents;
# tbi : trigger before insert
delimiter //
create trigger tbi_adherents
before insert on adherents
for each row
begin
set new.nom=upper(new.nom);
set new.prenom=concat(upper(substr(new.prenom,1,1)),
lower(substr(new.prenom,2,length(new.prenom)-1)));
end;
//
delimiter ;

drop trigger if exists tbu_adherents;


# tbi : trigger before update
delimiter //
create trigger tbu_adherents
before update on adherents
for each row
begin
if old.nom != new.nom then
set new.nom=upper(new.nom);
end if;
if old.prenom != new.prenom then
set new.prenom=concat(upper(substr(new.prenom,1,1)),
lower(substr(new.prenom,2,length(new.prenom)-1)));
end if;
end;
//
delimiter ;

10) On souhaite interdire l’emprunt d’un livre déjà emprunté. Ecrire le trigger.
drop trigger if exists tbi_emprunter;
# tbi : trigger before insert
delimiter //
create trigger tbi_emprunter
before insert on emprunter
for each row
begin
declare meserr integer;
declare vnl integer;
set vnl = null;
select nl into vnl from emprunter where nl=new.nl and dateret is null;
if vnl is not null then
select ‘le livre est déjà emprunté’ into @messerr;
select ‘le livre est déjà emprunté’ into meserr from livres;
# else
# update livres set libre=0 where nl=new.nl ;
# inutile avec le trigger after
end if ;
end;
//
delimiter ;

11) On souhaite interdire l’emprunt de plus de 3 livres par le même adhérent. Ecrire le
trigger.
drop trigger if exists tbi_emprunter;
# tbi : trigger before insert
delimiter //
create trigger tbi_emprunter
before insert on emprunter
for each row
begin
declare vnl integer;
declare vnbemp integer;
set vnl = null;
select nl into vnl from emprunter where nl=new.nl and dateret is null;
if vnl is not null then
select ‘le livre est déjà emprunté’ into @messerr;
select 1,2 into vnl;
else
select count(*) into vnbemp from emprunter where na=new.na ;
if vnbemp = 3 then
select concat(‘l\’adherent ’, new.na,’ a déjà emprunté 3 livres’)
into @messerr;
select 1,2 into vnl;
end if ;
end if ;
set new.dureeEmprunt = to_days(new.dateRet)-to_days(new.dateEmp);
end;
//
delimiter ;

12) On souhaite que la date de retour prenne automatiquement la valeur de la date du jour du
rendu du livre. On souhaite interdire un rendu le jour même de l’emprunt et que la date
de retour soit postérieur à la date d’emprunt. On souhaite interdire toute modification du
tuple. Ecrire le trigger.
drop trigger if exists tbu_emprunter;
# tbu : trigger before update
delimiter //
create trigger tbu_emprunter
before update on emprunter
for each row
begin
declare vnb integer;
if old.dateRet is not null
or (old.dateRet is null and
(old.nl!=new.nl or old.na!=new.na or old.dureeMax!=new.dureeMax)
)
then
select “un emprunt ne peut pas être modifié” into @messerr;
select 1,2 into vnb;
end if;
if current_date() = new.dateEmp then
select “un emprunt ne peut être rendu le jour de l’emprunt”
into @messerr;
select 1,2 into vnb;
end if;
if new.dateRet != current_date then
select “la date de retour doit être celle du jour” into @messerr;
select 1,2 into vnb;
end if;
set new.dureeEmprunt = to_days(new.dateRet)-to_days(new.dateEmp);
end;
//
delimiter ;

13) Après analyse, on décide de fusionner les tables LIVRES et OEUVRES en une seule
table : écrire le script de requêtes permettant de faire cette modification.
Alter table livres add titre varchar(150), add auteur varchar(100);

drop procedure if exists exo9;


delimiter //
create procedure exo9()
begin
declare i, vno int;
declare vauteur varchar(100);
declare vtitre varchar(150);
declare vide int;
declare curseur cursor for select no, titre, auteur from oeuvres;
declare continue handler for not found set vide = 1 ;
-- attention: si on met 0 ça boucle sans fin !!!

set i=1;
set vide=0;
open curseur;
maboucle: loop
fetch curseur into vno, vtitre, vauteur;
if vide=1 then
leave maboucle;
end if;
update livres set titre=vtitre, auteur=vauteur where no=vno;
set i=i+1;
end loop;
close curseur;
end ;
//
delimiter ;

call exo9();
select * from livres;

14) Ecrire le ou les triggers qui vérifient la cohérence des données suite à cette modification.
drop trigger if exists tbi_livres;
# tbi : trigger before insert
delimiter //
create trigger tbi_livres
before insert on livres
for each row
begin
declare meserr integer;
declare vnb int;
declare vauteur varchar(100);
declare vtitre varchar(150);
select count(*) into vnb from livres where no=new.no;
set @vnbout=vnb;
if vnb != 0 then
select titre, auteur into vtitre, vauteur
from livres where no=new.no limit 1;
if vauteur != new.auteur or vtitre != new.titre then
select ‘oeuvre incohérente’ into @messerr;
select ‘oeuvre incohérente’ into meserr from livres;
end if;
else
insert into oeuvres values (new.no, new.auteur, new.titre);
end if;
end;
//
delimiter ;

drop trigger if exists tbu_livres;


# tbu : trigger before update
delimiter //
create trigger tbu_livres
before update on livres
for each row
begin
declare meserr integer;
declare vnb int;
declare vauteur varchar(100);
declare vtitre varchar(150);

# si on a saisi une nouvelle valeur pour NO


if old.no != new.no then
select count(*) into vnb from livres where no=new.no;
set @vnbout=vnb;

# si la valeur saisie pour NO est déjà dans livres


if vnb != 0 then
# on récupère le titre et l’auteur du NO saisi
select titre, auteur into vtitre, vauteur
from livres where no=new.no limit 1;

# si on n’a pas change le titre et l’auteur,


# on passe au nouveau titre, nouvel auteur
if old.auteur=new.auteur and old.titre=new.titre then
set new.auteur=vauteur;
set new.titre=vtitre ;
end if ;

# si on a changé le titre ou l’auteur et que c’est différent


# de celui du NO, c’est incohérent
if vauteur != new.auteur or vtitre != new.titre then
select ‘oeuvre incohérente’ into @messerr;
select ‘oeuvre incohérente’ into meserr from livres;
end if;

# si la valeur saisie pour NO n’est pas dans livres


else
insert into oeuvres values (new.no, new.auteur, new.titre);
end if;

# si on n’a pas saisi de nouvelle valeur pour NO


elseif old.auteur !=new.auteur or old.titre!=new.titre then
select ‘oeuvre incohérente’ into @messerr;
select ‘oeuvre incohérente’ into meserr from livres;
end if;
end;
//
delimiter ;

You might also like