Il vincolo CHECK in MySQL non funziona

Per prima cosa ho creato un tavolo come

CREATE TABLE Customer ( SD integer CHECK (SD > 0), Last_Name varchar (30), First_Name varchar(30) ); 

e quindi inserito i valori in quella tabella

 INSERT INTO Customer values ('-2','abc','zz'); 

MySQL non mostra un errore, accetta i valori.

Il manuale di riferimento MySQL dice:

La clausola CHECK viene analizzata ma ignorata da tutti i motori di archiviazione.

Prova un innesco …

 mysql> delimiter // mysql> CREATE TRIGGER trig_sd_check BEFORE INSERT ON Customer -> FOR EACH ROW -> BEGIN -> IF NEW.SD<0 THEN -> SET NEW.SD=0; -> END IF; -> END -> // mysql> delimiter ; 

Spero possa aiutare.

Sfortunatamente MySQL non supporta i vincoli di controllo SQL. Puoi definirli nella tua query DDL per ragioni di compatibilità, ma sono semplicemente ignorati.

C’è un’alternativa semplice

È ansible creare i trigger BEFORE INSERT e BEFORE UPDATE che causano un errore o impostano il campo sul valore predefinito quando non vengono soddisfatti i requisiti dei dati.

Esempio per BEFORE INSERT funziona dopo MySQL 5.5

 DELIMITER $$ CREATE TRIGGER `test_before_insert` BEFORE INSERT ON `Test` FOR EACH ROW BEGIN IF CHAR_LENGTH( NEW.ID ) < 4 THEN SIGNAL SQLSTATE '12345' SET MESSAGE_TEXT := 'check constraint on Test.ID failed'; END IF; END$$ DELIMITER ; 

Prima di MySQL 5.5 si doveva causare un errore, ad es. Chiamare una procedura non definita.

In entrambi i casi ciò provoca un rollback implicito della transazione. MySQL non consente l'istruzione ROLLBACK stessa all'interno di procedure e trigger.

Se non si desidera eseguire il rollback della transazione (INSERT / UPDATE deve passare anche con un "check SET NEW.ID = NULL " non riuscito, è ansible sovrascrivere il valore utilizzando SET NEW.ID = NULL che imposterà l'id sul valore predefinito dei campi, non ha davvero senso per un id tho

Modifica: rimossa la citazione randagio.

Riguardo all'operatore: := :

A differenza di = , l'operatore := non viene mai interpretato come operatore di confronto. Ciò significa che è ansible utilizzare := in qualsiasi istruzione SQL valida (non solo nelle istruzioni SET) per assegnare un valore a una variabile.

https://dev.mysql.com/doc/refman/5.6/en/assignment-operators.html

Per quanto riguarda le virgolette dell'identificatore degli apici:

Il carattere di citazione dell'identificatore è l'apice ("` ")

Se la modalità SQL ANSI_QUOTES è abilitata, è anche ansible citare gli identificatori tra virgolette doppie

http://dev.mysql.com/doc/refman/5.6/en/identifiers.html

CHECK vincoli CHECK vengono ignorati da MySQL come spiegato in un minuscolo commento nei documenti: CREATE TABLE

La clausola CHECK viene analizzata ma ignorata da tutti i motori di archiviazione.

Il vincolo CHECK non sembra essere implementato in MySQL.

Vedi questo bug report: https://bugs.mysql.com/bug.php?id=3464

Come accennato da joanq MariaDB ora sembra supportare i vincoli di CHECK tra le altre chicche:

“Supporto per CHECK CONSTRAINT ( MDEV-7563 ).”

https://mariadb.com/kb/en/mariadb/mariadb-1021-release-notes/

prova con set sql_mode = 'STRICT_TRANS_TABLES' OR SET sql_mode='STRICT_ALL_TABLES'