Un trigger permet
Ils sont déclenchés par le SGBD lorsque certains évènements se produisent sur une table (insertion, mise à jour ou suppression) et sont exécutés sur chaque ligne concernée par la requête, soit avant soit après son execution.
On ne peut pas mettre de trigger sur des vues, y compris information_schema
et performance_schema
.
Un trigger ne peut pas utiliser de procédures qui mettent à jour les valeurs ni utiliser de transactions.
SHOW TRIGGERS
[FROM nom_database]
[LIKE '%pattern' | WHERE expr]
CREATE
[DEFINER = { user | CURRENT_USER }]
TRIGGER nom_trigger
{ BEFORE | AFTER } { INSERT | UPDATE | DELETE }
ON nom_table FOR EACH ROW
[{ FOLLOWS | PRECEDES } nom_autre_trigger]
corps_trigger
À l’intérieur du corps du trigger, on peut accéder aux valeurs de la ligne via OLD
et NEW
.
OLD
contient les anciennes valeurs de la ligne (update, delete), NEW
les nouvelles valeurs (insert, update).
-- Créer un trigger qui calcule le total `amount` des lignes insérées
CREATE TRIGGER ins_sum BEFORE INSERT ON account
FOR EACH ROW
SET @sum = @sum + NEW.amount;
--- Insérer des lignes
SET @sum = 0;
INSERT INTO account VALUES(137,14.98),(141,1937.50),(97,-100.00);
--- Total calculé
SELECT @sum AS 'Total amount inserted';
+-----------------------+
| Total amount inserted |
+-----------------------+
| 1852.48 |
+-----------------------+
Si le corps du trigger contient plusieurs intructions, le début et la fin doivent être délimité par BEGIN
et END
delimiter //
CREATE TRIGGER upd_check BEFORE UPDATE ON account
FOR EACH ROW
BEGIN
IF NEW.amount < 0 THEN
SET NEW.amount = 0;
ELSEIF NEW.amount > 100 THEN
SET NEW.amount = 100;
END IF;
END //
delimiter ;
Une erreur peut être levée avec SIGNAL
SIGNAL SQLSTATE '45000' set message_text='mon message';
CREATE TABLE IF NOT EXISTS employe (
id INT(11) UNSIGNED PRIMARY KEY,
nom VARCHAR(255),
prenom VARCHAR(255),
salaire_horaire FLOAT
);
INSERT IGNORE INTO employe VALUES
(1, 'Dupont', 'Jean', 35),
(2, 'Durand', 'Marie', 40),
(3, 'Dufour', 'Henri', 45);
DROP TRIGGER IF EXISTS t_verif_salaire;
DELIMITER //
CREATE TRIGGER t_verif_salaire BEFORE UPDATE ON employe
FOR EACH ROW
BEGIN
IF NEW.salaire_horaire < OLD.salaire_horaire THEN
SET @msg = CONCAT('Le salaire de l\'employé #', OLD.id, ' (', OLD.nom, ' ', OLD.prenom, ') ne peut pas diminuer');
SIGNAL SQLSTATE '45000' set message_text=@msg;
END IF;
END //
DELIMITER ;
UPDATE employe SET salaire_horaire = 30 WHERE salaire_horaire = 35;
-- #1644 - Le salaire de l'employé #1 (Dupont Jean) ne peut pas diminuer
DROP TRIGGER [IF EXISTS] nom_trigger
DROP TRIGGER test.ins_sum;