Vous pouvez exécuter le DBCC CHECKCONSTRAINTS
console pour renvoyer une liste de toutes les violations de contrainte dans une base de données SQL Server.
Cette commande vérifie l'intégrité d'une contrainte spécifiée ou de toutes les contraintes sur une table spécifiée dans la base de données courante. Il renvoie n'importe quelle clé étrangère et CHECK
violations de contrainte qu'il trouve.
Vous pouvez utiliser le ALL_CONSTRAINTS
option pour vérifier les contraintes activées et désactivées. Si vous l'omettez, seules les contraintes activées sont renvoyées (sauf si vous spécifiez explicitement une contrainte à vérifier, auquel cas elle sera renvoyée, qu'elle soit activée ou désactivée).
Exemple 1 :Violation des contraintes CHECK
J'ai exécuté cet exemple sur une base de données contenant des CHECK
violations de contraintes.
USE Test; DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;
Résultat :
+------------------------+-------------------+---------------------------------------------------------+ | Table | Constraint | Where | |------------------------+-------------------+---------------------------------------------------------| | [dbo].[Occupation] | [chkJobTitle] | [JobTitle] = 'Digital Nomad' | | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2020-01-01' AND [EndDate] = '1999-01-01' | | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2021-10-25' AND [EndDate] = '2021-10-24' | +------------------------+-------------------+---------------------------------------------------------+
Cela montre que j'ai trois violations de contrainte dans ma base de données.
Explication des colonnes
Les trois colonnes renvoient les informations suivantes :
- Tableau
- Nom du nom de la table qui contient la violation de contrainte.
- Contrainte
- Nom de la contrainte violée.
- Où
- Affectations de valeurs de colonne qui identifient la ou les lignes violant la contrainte. La valeur de cette colonne peut être utilisée dans un
WHERE
clause d'unSELECT
instruction interrogeant les lignes qui violent la contrainte.
Par conséquent, grâce à la troisième colonne, je peux maintenant trouver (et mettre à jour) toutes les données invalides.
Rechercher les données invalides
Donc, si nous regardons la première ligne de mon DBCC CHECKCONSTRAINTS
résultats, nous voyons que nous pouvons trouver les données incriminées en utilisant [JobTitle] = 'Digital Nomad'
dans un WHERE
clause.
Comme ceci :
SELECT * FROM [dbo].[Occupation] WHERE [JobTitle] = 'Digital Nomad';
Résultat :
+----------------+---------------+ | OccupationId | JobTitle | |----------------+---------------| | 7 | Digital Nomad | +----------------+---------------+
La définition de la contrainte
Jetons un coup d'œil à la définition réelle du chkJobTitle
contrainte :
SELECT Definition FROM sys.check_constraints WHERE name = 'chkJobTitle';
Résultat :
+-------------------------------+ | Definition | |-------------------------------| | ([JobTitle]<>'Digital Nomad') | +-------------------------------+
Cette contrainte indique que la valeur de JobTitle la colonne ne doit pas être Nomade Numérique , pourtant un nomade digital a quand même réussi à entrer dans ma base de données !
Mettre à jour les données incriminées
Vous pouvez soit mettre à jour les données incriminées, les supprimer ou les laisser telles quelles.
Dans cet exemple, j'utilise le même WHERE
clause pour mettre à jour la valeur :
UPDATE [dbo].[Occupation] SET [JobTitle] = 'Unemployed' WHERE [JobTitle] = 'Digital Nomad';
Maintenant, si je relance la vérification, cet enregistrement n'est plus un problème, et seuls les deux autres problèmes subsistent :
DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;
Résultat :
+------------------------+-------------------+---------------------------------------------------------+ | Table | Constraint | Where | |------------------------+-------------------+---------------------------------------------------------| | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2020-01-01' AND [EndDate] = '1999-01-01' | | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2021-10-25' AND [EndDate] = '2021-10-24' | +------------------------+-------------------+---------------------------------------------------------+
Exemple 2 :Violation des contraintes de clé étrangère
Dans cet exemple, je passe à une base de données qui contient quelques violations de contraintes de clé étrangère.
USE Music; DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;
Résultat :
+----------------+---------------------+--------------------+ | Table | Constraint | Where | |----------------+---------------------+--------------------| | [dbo].[Albums] | [FK_Albums_Artists] | [ArtistId] = '123' | | [dbo].[Albums] | [FK_Albums_Artists] | [ArtistId] = '17' | +----------------+---------------------+--------------------+
Dans ce cas, il semble que deux lignes dans les Albums table font référence à un ArtistId ça n'existe pas.
Rechercher les données invalides
Encore une fois, nous pouvons utiliser le
Où
colonne pour construire notre WHERE
clause. Cette fois, j'ajouterai les deux violations à mon WHERE
clause :
SELECT * FROM [dbo].[Albums] WHERE [ArtistId] = '123' OR [ArtistId] = '17';
Résultat :
+-----------+-------------+---------------+------------+-----------+ | AlbumId | AlbumName | ReleaseDate | ArtistId | GenreId | |-----------+-------------+---------------+------------+-----------| | 21 | Yo Wassup | 2019-03-12 | 17 | 3 | | 22 | Busted | 1901-05-11 | 123 | 3 | +-----------+-------------+---------------+------------+-----------+
Nous pouvons donc maintenant voir les deux lignes qui violent la contrainte (bien que ce ne soit que l' ArtistId colonne qui viole la contrainte).
Vérifiez la table de clé primaire
Nous pouvons confirmer la violation en interrogeant les Artistes table (c'est-à-dire la table qui contient la clé primaire de cette clé étrangère).
Exécutons donc la même requête sur les Artistes tableau.
SELECT * FROM [dbo].[Artists] WHERE [ArtistId] = '123' OR [ArtistId] = '17';
Résultat :
(0 rows affected)
Comme prévu, aucune valeur n'est dans cette table.
La clé étrangère est censée empêcher que cela se produise. Soit les données non valides sont entrées dans la base de données alors que la clé étrangère était désactivée, soit elles sont entrées avant la création de la clé étrangère. Dans tous les cas, lors de la création ou de l'activation d'une clé étrangère ou de CHECK
contrainte, vous devez utiliser WITH CHECK
pour spécifier que toutes les données existantes doivent être vérifiées avant d'activer la contrainte.
Exemple 3 - Vérifier uniquement les contraintes activées
Si vous souhaitez uniquement vérifier les contraintes actuellement activées, supprimez WITH ALL_CONSTRAINTS
:
USE Test; DBCC CHECKCONSTRAINTS;
Résultat :
+--------------------+---------------+------------------------------+ | Table | Constraint | Where | |--------------------+---------------+------------------------------| | [dbo].[Occupation] | [chkJobTitle] | [JobTitle] = 'Digital Nomad' | +--------------------+---------------+------------------------------+
Ainsi, sur les deux contraintes qui ont été violées, il semble que chkJobTitle est le seul qui a été activé.
Nous pouvons vérifier cela avec la requête suivante :
SELECT name, is_disabled FROM sys.check_constraints WHERE name = 'chkValidEndDate' OR name = 'chkJobTitle';
Résultat :
+-----------------+---------------+ | name | is_disabled | |-----------------+---------------| | chkJobTitle | 0 | | chkValidEndDate | 1 | +-----------------+---------------+
Exemple 4 - Vérifier uniquement les contraintes pour une table donnée
Vous pouvez ajouter le nom d'une table entre parenthèses si vous souhaitez uniquement vérifier les contraintes de cette table :
USE Test; DBCC CHECKCONSTRAINTS(ConstraintTest) WITH ALL_CONSTRAINTS;
Résultat :
+------------------------+-------------------+---------------------------------------------------------+ | Table | Constraint | Where | |------------------------+-------------------+---------------------------------------------------------| | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2020-01-01' AND [EndDate] = '1999-01-01' | | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2021-10-25' AND [EndDate] = '2021-10-24' | +------------------------+-------------------+---------------------------------------------------------+
Exemple 5 - Vérifier une seule contrainte
Vous pouvez vérifier une seule contrainte en plaçant son nom entre parenthèses :
USE Test; DBCC CHECKCONSTRAINTS(chkValidEndDate);
Résultat :
+------------------------+-------------------+---------------------------------------------------------+ | Table | Constraint | Where | |------------------------+-------------------+---------------------------------------------------------| | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2020-01-01' AND [EndDate] = '1999-01-01' | | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2021-10-25' AND [EndDate] = '2021-10-24' | +------------------------+-------------------+---------------------------------------------------------+
Lorsque vous spécifiez une seule contrainte, le WITH ALL_CONSTRAINTS
n'a aucun effet :
USE Test; DBCC CHECKCONSTRAINTS(chkValidEndDate) WITH ALL_CONSTRAINTS;
Résultat :
+------------------------+-------------------+---------------------------------------------------------+ | Table | Constraint | Where | |------------------------+-------------------+---------------------------------------------------------| | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2020-01-01' AND [EndDate] = '1999-01-01' | | [dbo].[ConstraintTest] | [chkValidEndDate] | [StartDate] = '2021-10-25' AND [EndDate] = '2021-10-24' | +------------------------+-------------------+---------------------------------------------------------+