Dans SQL Server, vous pouvez créer un CHECK
contrainte dans une table pour spécifier les valeurs de données acceptables dans une ou plusieurs colonnes.
Si une table a un CHECK
contrainte dessus, et vous essayez de fournir des données qui ne sont pas conformes à la CHECK
contrainte, l'opération échouera avec une erreur.
Cela aide à maintenir l'intégrité des données, car cela aide à empêcher que des données non valides entrent dans la base de données.
Lorsque vous créez un CHECK
contrainte, vous fournissez une expression logique qui renvoie TRUE
ou FALSE
. Cette expression logique est utilisée pour vérifier les données.
CHECK
Les contraintes sont similaires aux contraintes de clé étrangère car elles contrôlent les valeurs placées dans une colonne. Cependant, la différence réside dans la manière dont elles déterminent les valeurs valides :les contraintes de clé étrangère obtiennent la liste des valeurs valides d'une autre table, tandis que CHECK
les contraintes déterminent les valeurs valides à partir d'une expression logique.
Les contraintes peuvent être définies au niveau de la colonne ou au niveau de la table. Une contrainte au niveau de la colonne s'applique uniquement aux données de cette colonne. Une contrainte au niveau de la table s'applique à toute la ligne et vérifie les données de plusieurs colonnes.
Vous trouverez ci-dessous des exemples de création de CHECK
au niveau de la colonne et de la table. contraintes.
Exemple 1 – Créer une contrainte CHECK au niveau de la colonne
Voici un exemple de création d'un CHECK
de base au niveau de la colonne contrainte lors de la création d'une table.
CREATE TABLE ConstraintTest ( ConstraintTestId int IDENTITY(1,1) NOT NULL PRIMARY KEY, Price smallmoney NOT NULL, CONSTRAINT chkPrice CHECK (Price > 0) );
Dans ce cas, le CHECK
contrainte spécifie que toutes les données du Price
doit être supérieur à 0. En d'autres termes, le prix ne peut pas être nul et il ne peut pas être négatif. Il s'agit d'une contrainte au niveau de la colonne, car elle s'applique aux données d'une seule colonne.
Comme il s'agit d'une contrainte au niveau de la colonne, j'aurais pu la définir dans le cadre de la colonne (sans la virgule). Donc j'aurais pu faire ça :
CREATE TABLE ConstraintTest ( ConstraintTestId int IDENTITY(1,1) NOT NULL PRIMARY KEY, Price smallmoney NOT NULL CONSTRAINT chkPrice CHECK (Price > 0) );
Dans tous les cas, essayons d'insérer une valeur invalide :
INSERT INTO ConstraintTest ( Price ) VALUES ( 0 );
Résultat :
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkPrice". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'Price'.
Exemple 2 – Ajouter d'autres colonnes et une autre contrainte CHECK au niveau de la colonne
Ajoutons quelques colonnes supplémentaires à notre table, puis ajoutons un autre CHECK
au niveau de la colonne contrainte.
ALTER TABLE ConstraintTest ADD TeamSize tinyint NOT NULL, StartDate date NOT NULL, EndDate date NOT NULL, CONSTRAINT chkTeamSize CHECK (TeamSize >= 3 AND TeamSize <= 15) ;
L'une des nouvelles colonnes enregistre le nombre de membres de l'équipe. Dans ce cas, la règle métier est qu'une équipe doit avoir au moins 3 membres, mais pas plus de 15. Par conséquent, la base de données doit empêcher la situation où une équipe compte moins de 3 membres ou plus de 15.
Essayons d'insérer une valeur invalide :
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 1, 2, '2020-01-01', '1900-02-02' );
Résultat :
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkTeamSize". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'TeamSize'.
Exemple 3 – Ajouter une contrainte CHECK au niveau de la table
Ajoutons maintenant une contrainte au niveau de la table. Cela vérifiera les données dans deux colonnes.
Au fait, vous n'avez pas besoin d'ajouter une autre colonne pour ajouter un CHECK
contrainte. Vous pouvez simplement ajouter la contrainte par elle-même.
Exemple :
ALTER TABLE ConstraintTest ADD CONSTRAINT chkValidEndDate CHECK (EndDate >= StartDate) ;
Dans ce cas, j'ajoute une contrainte pour garantir que la date de fin ne peut jamais être antérieure à la date de début. Ceci vérifie les données sur deux colonnes et est donc une contrainte au niveau de la table.
Essayez d'insérer une valeur invalide :
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 1, 3, '2020-01-01', '1900-02-02' );
Résultat :
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkValidEndDate". The conflict occurred in database "Test", table "dbo.ConstraintTest".
Notez que pour tester cette contrainte, j'ai dû augmenter les membres de l'équipe à 3 pour éviter que la contrainte précédente ne soit déclenchée en premier (CHECK
les contraintes sont validées dans l'ordre de leur création).
Exemple 4 - Modifier une contrainte CHECK
Vous ne pouvez pas réellement modifier un CHECK
contrainte. Si vous devez le modifier, vous devrez le supprimer et le créer avec la nouvelle définition.
Exemple :
ALTER TABLE ConstraintTest DROP CONSTRAINT chkTeamSize; ALTER TABLE ConstraintTest ADD CONSTRAINT chkTeamSize CHECK (TeamSize >= 5 AND TeamSize <= 20) ;
Comme mentionné, CHECK
les contraintes sont validées dans l'ordre dans lequel elles sont créées, ce qui peut affecter l'erreur détectée en premier.
Par conséquent, dans ce cas, si j'essaie d'insérer une valeur invalide (et d'inclure également des dates invalides), les dates invalides seront interceptées en premier :
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 1, 4, '2020-01-01', '1900-02-02' );
Résultat :
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkValidEndDate". The conflict occurred in database "Test", table "dbo.ConstraintTest".
Donc, afin de vérifier ma dernière contrainte, je dois d'abord résoudre le problème de date :
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 1, 4, '2020-01-01', '2020-02-02' );
Résultat :
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkTeamSize". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'TeamSize'.
Ma dernière contrainte fonctionne donc comme prévu.
Exemple 5 – CHECK Constraints et colonnes IDENTITY
Maintenant que nous avons testé les contraintes, allons-y et insérons des données valides :
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 1, 5, '2020-01-01', '2020-02-02' );
Résultat :
+--------------------+---------+------------+-------------+------------+ | ConstraintTestId | Price | TeamSize | StartDate | EndDate | |--------------------+---------+------------+-------------+------------| | 13 | 1.0000 | 5 | 2020-01-01 | 2020-02-02 | +--------------------+---------+------------+-------------+------------+
Enfin, nous obtenons une insertion réussie.
Cependant, vous remarquerez que le IDENTITY
la colonne a déjà augmenté à 13.
Rappelez-vous que lorsque j'ai créé la table pour la première fois, j'ai défini le ConstraintTestId
colonne pour utiliser IDENTITY(1,1)
, ce qui signifie qu'il doit commencer à 1 et s'incrémenter automatiquement de 1 à chaque insertion de ligne.
Mais maintenant que j'ai enfin inséré ma première ligne, la valeur est déjà 13. C'est parce que le IDENTITY
la colonne est incrémentée même lorsqu'un CHECK
contrainte provoque le INSERT
l'opération échoue.
Notez que j'ai fait quelques insertions ratées supplémentaires lors de la création des exemples pour cet article, de sorte que la valeur a augmenté à une valeur supérieure à celle que vous obtiendrez si vous suivez simplement étape par étape cet article.
Dans tous les cas, faisons une dernière insertion ratée, puis une réussie pour le confirmer.
Échec de l'insertion :
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 2, 4, '2020-01-02', '2020-02-03' );
Résultat :
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkTeamSize". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'TeamSize'.
Insertion réussie :
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 2, 6, '2020-01-02', '2020-02-03' ); SELECT * FROM ConstraintTest;
Résultat :
+--------------------+---------+------------+-------------+------------+ | ConstraintTestId | Price | TeamSize | StartDate | EndDate | |--------------------+---------+------------+-------------+------------| | 13 | 1.0000 | 5 | 2020-01-01 | 2020-02-02 | | 15 | 2.0000 | 6 | 2020-01-02 | 2020-02-03 | +--------------------+---------+------------+-------------+------------+
Nous pouvons voir que le IDENTITY
la colonne saute de 13 à 15, elle a donc évidemment été incrémentée lors de l'échec de l'insertion.
Quelques restrictions des contraintes CHECK
Voici quelques restrictions à prendre en compte lorsque vous travaillez avec CHECK
contraintes :
- La condition de recherche doit correspondre à une expression booléenne et ne peut pas faire référence à une autre table.
- L'expression ne peut pas contenir de types de données d'alias.
CHECK
les contraintes ne peuvent pas être définies sur le texte , texte , ou image colonnes.