MySQL Trigger per prevenire INSERT in determinate condizioni

Voglio fare un trigger che impedirà l’inserimento se la data di nascita (una delle colonne) è in futuro. Ho questo:

CREATE TRIGGER foo BEFORE INSERT ON table FOR EACH ROW BEGIN IF NEW.birthdate > CURRENT_DATE() THEN //How do I prevent the insert right here??? END IF; END; 

Come posso cancellare l’inserto all’interno dell’istruzione if?

Sulla base di questo non sono sicuro se sia ansible farlo in quel modo.

Non c’è alcun supporto nell’attuale implementazione di trigger di MySQL per lanciare volontariamente un’eccezione e interrompere l’istruzione che ha generato il trigger.

La soluzione che ho trovato è scrivere un trigger BEFORE per impostare una delle colonne not-NULL nella tabella su NULL, violando così il suo vincolo NOT NULL. Questo fa sì che l’affermazione che ha generato il trigger sia stata interrotta.

Esempio 1, MySQL, è ansible annullare quell’inserimento nel trigger con il signal sqlstate

  1. Crea la tua tabella con una colonna varchar:

     mysql> create table yar (val VARCHAR(25) not null); Query OK, 0 rows affected (0.02 sec) 
  2. Crea il trigger “prima dell’inserimento” per verificare una condizione e non consentire.

     mysql> delimiter $$ mysql> create trigger foo before insert on yar -> for each row -> begin -> if new.val = '' then -> signal sqlstate '45000'; -> end if; -> end;$$ Query OK, 0 rows affected (0.01 sec) 
  3. Prova ad inserire dove è soddisfatta la condizione:

     mysql> delimiter ; mysql> insert into yar values(""); ERROR 1644 (45000): Unhandled user-defined exception condition mysql> insert into yar values ("abc"); Query OK, 1 row affected (0.01 sec) mysql> select * from yar; +-----+ | val | +-----+ | abc | +-----+ 1 row in set (0.00 sec) 

Hai inserito una stringa vuota, il grilletto ha visto che era vuoto e ha sollevato il segnale per impedire l’inserimento.

Esempio 2, MySQL, annulla l’inserimento nel trigger facendo sì che i dati violino un vincolo non nullo.

  1. Crea la tua tabella con una colonna varchar:

     mysql> create table yar (val VARCHAR(25) not null); Query OK, 0 rows affected (0.02 sec) 
  2. Crea il trigger “prima dell’inserimento” per verificare una condizione e non consentire.

     mysql> delimiter $$ mysql> create trigger foo before insert on yar -> for each row -> begin -> if new.val = '' then -> set new.val = NULL; -> end if; -> end;$$ Query OK, 0 rows affected (0.01 sec) 
  3. Prova ad inserire dove è soddisfatta la condizione:

     mysql> delimiter ; mysql> insert into yar values(""); ERROR 1048 (23000): Column 'val' cannot be null mysql> insert into yar values ("abc"); Query OK, 1 row affected (0.01 sec) mysql> select * from yar; +-----+ | val | +-----+ | abc | +-----+ 1 row in set (0.00 sec) 

Hai inserito una stringa vuota, il trigger ha visto che era vuoto e ha cambiato il valore in null, quindi l’inserimento è stato impedito.

Non so se è tardi ma puoi farlo ora:

 SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = "your error text"; 

PS Non dimenticare di modificare il delimitatore prima e dopo il trigger …

 DELIMITER $$ CREATE TRIGGER foo BEFORE INSERT ON table FOR EACH ROW BEGIN IF NEW.birthdate > CURRENT_DATE() THEN SIGNAL SQLSTATE '02000' SET MESSAGE_TEXT = 'Warning: birthdate can not be greater than current date!'; END IF; END$$ DELIMITER ; 

Ho avuto lo stesso problema. Ho creato una tabella ma non c’era modo di assegnare la lunghezza minima della stringa in MySQL. Ho creato la tabella come segue:

 CREATE TABLE Users ( UserName varchar(15) NOT NULL PRIMARY KEY, Password varchar(15) NOT NULL, Active Bool DEFAULT TRUE, CHECK (CHAR_LENGTH(UserName)>3) ) 

Ma la funzione CHECK non funziona su insert.

Così ho cambiato il mio tavolo come segue:

 CREATE TABLE Users ( UserName varchar(15) NOT NULL PRIMARY KEY, Password varchar(15) NOT NULL, Active Bool DEFAULT TRUE ) 

Successivamente, crea un trigger:

 delimiter $$ CREATE TRIGGER myTrigger BEFORE INSERT ON Users FOR EACH ROW BEGIN IF CHAR_LENGTH(NEW.UserName) < 4 THEN DELETE FROM Users WHERE Users.UserName=NEW.UserName; END if; END$$ delimiter ; 

Il problema descritto nella domanda sembra un candidato perfetto per un vincolo CHECK – aggiungi questa linea alla definizione della tabella.

CONSTRAINT born_in_the_past CHECK (data di nascita <= now ())