Bases de Données MySQL Triggers Corrigé
Bases de Données MySQL Triggers Corrigé
MySQL – Triggers
Corrigé
Bertrand LIAUDET
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
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;
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);
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 ;
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.
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 ;
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);
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 ;