Tout d'abord, éliminons les erreurs de syntaxe de votre tentative initiale :
- Au lieu de
FOR EACH STATEMENT
, il devrait êtreFOR EACH ROW
. - Puisque vous avez déjà défini le délimiteur sur
//
; vous devez utiliser//
(au lieu de;
) dans leDROP TRIGGER IF EXISTS ..
déclaration. Row_Count()
aura la valeur 0 dans unBefore Delete Trigger
, car aucune ligne n'a encore été mise à jour. Cette approche ne fonctionnera donc pas.
Maintenant, l'astuce consiste à utiliser Accessible au niveau de la session (et persistant) variables définies par l'utilisateur
. Nous pouvons définir une variable, disons @rows_being_deleted
, et vérifiez plus tard s'il est déjà défini ou non.
For Each Row
exécute le même ensemble d'instructions pour chaque ligne supprimée . Donc, nous allons juste vérifier si la variable de session existe déjà ou non. Si ce n'est pas le cas, nous pouvons le définir. Donc, fondamentalement, pour la première ligne (en cours de suppression), elle sera définie, qui persistera tant que la session sera là.
Maintenant, s'il y a plus de lignes à supprimer, Trigger exécutera le même ensemble d'instructions pour les lignes restantes. Dans la deuxième ligne, la variable précédemment définie serait trouvée maintenant, et nous pouvons simplement lancer une exception maintenant.
Remarque qu'il est possible qu'au cours de la même session, plusieurs instructions de suppression soient déclenchées. Donc, avant de lancer une exception, nous devons définir le @rows_being_deleted
valeur à null
.
Ce qui suit fonctionnera :
DELIMITER //
DROP TRIGGER IF EXISTS prevent_multiple_deletion //
CREATE TRIGGER prevent_multiple_deletion
BEFORE DELETE ON `test`
FOR EACH ROW
BEGIN
-- check if the variable is already defined or not
IF( @rows_being_deleted IS NULL ) THEN
SET @rows_being_deleted = 1; -- set its value
ELSE -- it already exists and we are in next "row"
-- just for testing to check the row count
-- SET @rows_being_deleted = @rows_being_deleted + 1;
-- We have to reset it to null, as within same session
-- another delete statement may be triggered.
SET @rows_being_deleted = NULL;
-- throw exception
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Cannot delete more than one order per time!';
END IF;
END //
DELIMITER ;
Démo DB Fiddle 1 :Tentative de suppression de plusieurs lignes.
DELETE FROM `test` WHERE `id`< 5;
Résultat :
DB Fiddle Demo 2 :Tentative de suppression d'une seule ligne
Requête 1
DELETE FROM `test` WHERE `id` = 1;
Requête n° 2
SELECT * FROM `test`;
| id | a | b |
| --- | --- | --- |
| 2 | 3 | 4 |