web-dev-qa-db-fra.com

La contrainte CHECK dans MySQL ne fonctionne pas

J'ai d'abord créé une table comme

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

puis inséré des valeurs dans cette table

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

MySQL ne montre pas d'erreur, il accepte les valeurs.

116
JohnRaja

MySQL 8.0.16 est la première version qui prend en charge les contraintes CHECK.

Lire https://dev.mysql.com/doc/refman/8.0/en/create-table-check-constraints.html

Si vous utilisez MySQL 8.0.15 ou version antérieure, le Manuel de référence MySQL dit: 

La clause CHECK est analysée mais ignorée par tous les moteurs de stockage.

Essayez un déclencheur ...

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 ;

J'espère que cela pourra aider.

120
David Kerins

Malheureusement, MySQL ne supporte pas les contraintes de vérification SQL. Vous pouvez les définir dans votre requête DDL pour des raisons de compatibilité, mais elles sont simplement ignorées.

Il existe une alternative simple

Vous pouvez créer des déclencheurs BEFORE INSERT et BEFORE UPDATE qui provoquent une erreur ou définissent le champ sur sa valeur par défaut lorsque les exigences des données ne sont pas satisfaites.

Exemple pour BEFORE INSERT fonctionnant après 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 ;  

Avant MySQL 5.5, vous deviez générer une erreur, par exemple. appeler une procédure non définie.

Dans les deux cas, cela entraîne une annulation implicite de la transaction . MySQL n'autorise pas l'instruction ROLLBACK elle-même dans les procédures et les déclencheurs.

Si vous ne voulez pas annuler la transaction (INSERT/UPDATE devrait passer même avec une "contrainte de vérification" échouée, vous pouvez écraser la valeur en utilisant SET NEW.ID = NULL qui définira l'id sur la valeur par défaut des champs, cela n'a pas vraiment de sens pour id tho

Edit: Suppression de la citation parasite.

Concernant l'opérateur :=:

Contrairement à =, l'opérateur := n'est jamais interprété comme un opérateur de comparaison. Cela signifie que vous pouvez utiliser := dans toute instruction SQL valide (pas seulement dans les instructions SET) pour affecter une valeur à une variable.

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

Concernant les citations d'identifiant de backtick:

Le caractère de citation est le backtick (“` ”)

Si le mode SQL ANSI_QUOTES est activé, il est également possible de citer des identificateurs entre guillemets doubles.

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

70
Michel Feldheim

Les contraintes CHECK sont ignorées par MySQL, comme expliqué dans un minuscule commentaire dans la documentation: CREATE TABLE

La clause CHECK est analysée mais ignorée par tous les moteurs de stockage.

49
ypercubeᵀᴹ

La contrainte CHECK ne semble pas être implémentée dans MySQL.

Voir ce rapport de bogue: https://bugs.mysql.com/bug.php?id=3464

15
ryanprayogo

Comme mentionné par joanq, MariaDB semble désormais prendre en charge les contraintes de CHECK, entre autres avantages:

"Prise en charge de CHECK CONSTRAINT ( MDEV-7563 )."

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

8
Markus Barthlen

Les contraintes de vérification sont prises en charge à partir de la version 8.0.15 (à publier)

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

[23 janvier 16:24] Paul Dubois

Publié par développeur: corrigé dans 8.0.15.

Auparavant, MySQL permettait une forme limitée de syntaxe de contrainte CHECK, mais analysé et ignoré. MySQL implémente maintenant les fonctionnalités principales de contraintes de contrôle de table et de colonne, pour tous les moteurs de stockage . Les contraintes sont définies à l'aide des instructions CREATE TABLE et ALTER TABLE.

0
James

Mettez à jour MySQL 8.0.16 pour utiliser checks:

Depuis MySQL 8.0.16, CREATE TABLE autorise les fonctionnalités principales de table et contraintes de vérification de colonne, pour tous les moteurs de stockage. CREATE TABLE autorise la syntaxe de contrainte CHECK suivante, pour les deux tables contraintes et contraintes de colonne

Documentation MySQL Checks

0
sdlins