sql >> Database teknologi >  >> RDS >> Mysql

MySQL Before Delete trigger for at undgå at slette flere rækker

For det første, at få nogle syntaksfejl ud af vejen fra dit oprindelige forsøg:

  • I stedet for FOR EACH STATEMENT , skal det være FOR EACH ROW .
  • Da du allerede har defineret afgrænseren til //; du skal bruge // (i stedet for ; ) i DROP TRIGGER IF EXISTS .. erklæring.
  • Row_Count() vil have 0-værdi i en Before Delete Trigger , da ingen rækker er blevet opdateret endnu. Så denne tilgang vil ikke fungere.

Nu er tricket her at bruge Sessionsniveau tilgængelig (og vedvarende) brugerdefinerede variabler . Vi kan definere en variabel, lad os sige @rows_being_deleted , og senere kontrollere, om det allerede er defineret eller ej.

For Each Row kører det samme sæt sætninger for hver række der bliver slettet . Så vi vil bare kontrollere, om sessionsvariablen allerede eksisterer eller ej. Hvis det ikke gør det, kan vi definere det. Så dybest set, for den første række (ved at blive slettet), vil den blive defineret, hvilket vil vare ved, så længe sessionen er der.

Hvis der nu er flere rækker, der skal slettes, vil Trigger køre det samme sæt sætninger for de resterende rækker. I den anden række ville den tidligere definerede variabel blive fundet nu, og vi kan simpelthen smide en undtagelse nu.

Bemærk at der er en chance for, at flere delete-sætninger kan blive udløst inden for samme session. Så før vi kaster undtagelsen, skal vi indstille @rows_being_deleted værdi tilbage til null .

Følgende vil virke:

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 ;

DB Fiddle Demo 1 :Forsøger at slette mere end række.

DELETE FROM `test` WHERE `id`< 5;

Resultat:

DB Fiddle Demo 2 :Forsøger kun at slette én række

Forespørgsel #1

DELETE FROM `test` WHERE `id` = 1;

Forespørgsel #2

SELECT * FROM `test`;

| id  | a   | b   |
| --- | --- | --- |
| 2   | 3   | 4   |



  1. MySQL indsætter ikke en omvendt skråstreg

  2. Oracle fejlhåndtering

  3. Introduktion til Oracle RMAN

  4. Sådan forbinder du MySQL til Java-program