13.1.20.6 CHECK Constraints
Prior to MySQL 8.0.16, CREATE TABLE
permits only the following limited version of table CHECK
constraint syntax, which is parsed and ignored:
CHECK (expr)
As of MySQL 8.0.16, CREATE TABLE
permits the core features of table and column CHECK
constraints, for all storage engines. CREATE TABLE
permet la syntaxe de contrainte suivante CHECK
, pour les contraintes de table et de colonne :
] CHECK (expr) ENFORCED]
L’option symbol
spécifie un nom pour la contrainte. Si elle est omise, MySQL génère un nom à partir du nom de la table, un littéral _chk_
et un nombre ordinal (1, 2, 3,…). Les noms de contraintes ont une longueur maximale de 64 caractères. Ils sont sensibles à la casse, mais pas à l’accent.
expr
spécifie la condition de contrainte sous forme d’expression booléenne qui doit être évaluée en valeurs TRUE
ou UNKNOWN
(pour les valeurs NULL
) pour chaque ligne de la table. Si la condition est évaluée à FALSE
, elle échoue et une violation de contrainte se produit. L’effet d’une violation dépend de l’instruction en cours d’exécution, comme décrit plus loin dans cette section.
La clause d’exécution facultative indique si la contrainte est appliquée:
-
Si elle est omise ou spécifiée comme
ENFORCED
, la contrainte est créée et appliquée. -
Si elle est spécifiée comme
NOT ENFORCED
, la contrainte est créée mais n’est pas appliquée.
A CHECK
la contrainte est spécifiée comme une contrainte de table ou une contrainte de colonne :
-
Une contrainte de table n’apparaît pas dans une définition de colonne et peut faire référence à une ou plusieurs colonnes de table. Les références directes sont autorisées aux colonnes apparaissant plus loin dans la définition de la table.
-
Une contrainte de colonne apparaît dans une définition de colonne et ne peut se référer qu’à cette colonne.
Considérez cette définition de table :
CREATE TABLE t1( CHECK (c1 <> c2), c1 INT CHECK (c1 > 10), c2 INT CONSTRAINT c2_positive CHECK (c2 > 0), c3 INT CHECK (c3 < 100), CONSTRAINT c1_nonzero CHECK (c1 <> 0), CHECK (c1 > c3));
La définition inclut des contraintes de table et des contraintes de colonne, dans des formats nommés et non nommés :
-
La première contrainte est une contrainte de table : Elle se produit en dehors de toute définition de colonne, elle peut donc et fait référence à plusieurs colonnes de table. Cette contrainte contient des références directes à des colonnes non encore définies. Aucun nom de contrainte n’est spécifié, donc MySQL génère un nom.
-
Les trois contraintes suivantes sont des contraintes de colonne : Chacune se produit dans une définition de colonne, et ne peut donc se référer qu’à la colonne en cours de définition. L’une des contraintes est nommée explicitement. MySQL génère un nom pour chacun des deux autres.
-
Les deux dernières contraintes sont des contraintes de table. L’un d’eux est nommé explicitement. MySQL génère un nom pour l’autre.
Comme mentionné, MySQL génère un nom pour toute contrainte CHECK
spécifiée sans contrainte. Pour voir les noms générés pour la définition de table précédente, utilisez SHOW CREATE TABLE
:
mysql> SHOW CREATE TABLE t1\G*************************** 1. row *************************** Table: t1Create Table: CREATE TABLE `t1` ( `c1` int(11) DEFAULT NULL, `c2` int(11) DEFAULT NULL, `c3` int(11) DEFAULT NULL, CONSTRAINT `c1_nonzero` CHECK ((`c1` <> 0)), CONSTRAINT `c2_positive` CHECK ((`c2` > 0)), CONSTRAINT `t1_chk_1` CHECK ((`c1` <> `c2`)), CONSTRAINT `t1_chk_2` CHECK ((`c1` > 10)), CONSTRAINT `t1_chk_3` CHECK ((`c3` < 100)), CONSTRAINT `t1_chk_4` CHECK ((`c1` > `c3`))) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
Le standard SQL spécifie que tous les types de contraintes (clé primaire, index unique, clé étrangère, vérification) appartiennent au même espace de noms. Dans MySQL, chaque type de contrainte a son propre espace de noms par schéma (base de données). Par conséquent, les noms de contraintes CHECK
doivent être uniques par schéma; aucune table dans le même schéma ne peut partager un nom de contrainte CHECK
. (Exception : Une table TEMPORARY
masque une table non TEMPORARY
du même nom, elle peut donc également avoir les mêmes noms de contraintes CHECK
.)
Le début des noms de contraintes générés avec le nom de la table permet d’assurer l’unicité du schéma car les noms de table doivent également être uniques dans le schéma.
CHECK
les expressions de condition doivent respecter les règles suivantes. Une erreur se produit si une expression contient des constructions interdites.
-
Les colonnes non générées et générées sont autorisées, à l’exception des colonnes avec l’attribut
AUTO_INCREMENT
et des colonnes dans d’autres tables. -
Les littéraux, les fonctions intégrées déterministes et les opérateurs sont autorisés. Une fonction est déterministe si, avec les mêmes données dans les tables, plusieurs invocations produisent le même résultat, indépendamment de l’utilisateur connecté. Exemples de fonctions non déterministes qui échouent à cette définition :
CONNECTION_ID()
CURRENT_USER()
NOW()
. -
Les fonctions stockées et les fonctions définies par l’utilisateur ne sont pas autorisées.
-
Les paramètres de procédure et de fonction stockés ne sont pas autorisés.
-
Les variables (variables système, variables définies par l’utilisateur et variables locales de programme stockées) ne sont pas autorisées.
-
Les sous-requêtes ne sont pas autorisées.
Les actions référentielles de clé étrangère (ON UPDATE
ON DELETE
) sont interdites sur les colonnes utilisées dans les contraintes CHECK
. Likewise, CHECK
constraints are prohibited on columns used in foreign key referential actions.
CHECK
constraints are evaluated for INSERT
UPDATE
REPLACE
LOAD DATA
, and LOAD XML
statements and an error occurs if a constraint evaluates to FALSE
. En cas d’erreur, la gestion des modifications déjà appliquées diffère pour les moteurs de stockage transactionnels et non transactionnels, et dépend également de l’efficacité du mode SQL strict, comme décrit dans Mode SQL strict.
CHECK
les contraintes sont évaluées pour INSERT IGNORE
UPDATE IGNORE
LOAD DATA ... IGNORE
, et LOAD XML ... IGNORE
instructions et un avertissement se produit si une contrainte est évaluée à FALSE
. L’insertion ou la mise à jour de toute ligne incriminée est ignorée.
Si l’expression de contrainte évalue un type de données différent du type de colonne déclaré, la coercition implicite au type déclaré se produit selon les règles habituelles de conversion de type MySQL. Voir la Section 12.3, » Conversion de type dans l’Évaluation d’expression « ” Si la conversion de type échoue ou entraîne une perte de précision, une erreur se produit.
L’évaluation de l’expression de contrainte utilise le mode SQL en vigueur au moment de l’évaluation. Si un composant de l’expression dépend du mode SQL, des résultats différents peuvent se produire pour différentes utilisations de la table, sauf si le mode SQL est le même pendant toutes les utilisations.