Sie können DBCC CHECKCONSTRAINTS
ausführen console-Befehl, um eine Liste aller Beschränkungsverletzungen in einer SQL Server-Datenbank zurückzugeben.
Dieser Befehl prüft die Integrität einer angegebenen Einschränkung oder aller Einschränkungen für eine angegebene Tabelle in der aktuellen Datenbank. Es gibt einen beliebigen Fremdschlüssel und CHECK
zurück Einschränkungsverletzungen, die es findet.
Sie können die ALL_CONSTRAINTS
verwenden Option, um sowohl aktivierte als auch deaktivierte Einschränkungen zu überprüfen. Wenn Sie dies weglassen, werden nur aktivierte Einschränkungen zurückgegeben (es sei denn, Sie geben explizit eine zu prüfende Einschränkung an, in diesem Fall wird sie unabhängig davon zurückgegeben, ob sie aktiviert oder deaktiviert ist).
Beispiel 1 – Verletzung von CHECK-Einschränkungen
Ich habe dieses Beispiel mit einer Datenbank ausgeführt, die CHECK
enthält Beschränkungsverletzungen.
USE Test; DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;
Ergebnis:
+------------------------+-------------------+---------------------------------------------------------+ | 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' | +------------------------+-------------------+---------------------------------------------------------+
Dies zeigt, dass ich drei Beschränkungsverletzungen in meiner Datenbank habe.
Erklärung der Spalten
Die drei Spalten geben die folgenden Informationen zurück:
- Tabelle
- Name des Tabellennamens, der die Einschränkungsverletzung enthält.
- Einschränkung
- Name der Einschränkung, die verletzt wird.
- Wo
- Spaltenwertzuweisungen, die die Zeile oder Zeilen identifizieren, die gegen die Beschränkung verstoßen. Der Wert in dieser Spalte kann in einem
WHERE
verwendet werden -Klausel einesSELECT
-Anweisung, die Zeilen abfragt, die gegen die Einschränkung verstoßen.
Daher kann ich dank der dritten Spalte jetzt alle ungültigen Daten finden (und aktualisieren).
Ungültige Daten finden
Betrachten wir also die erste Zeile meiner DBCC CHECKCONSTRAINTS
Ergebnisse sehen wir, dass wir die anstößigen Daten finden können, indem wir [JobTitle] = 'Digital Nomad'
verwenden in einem WHERE
Klausel.
So:
SELECT * FROM [dbo].[Occupation] WHERE [JobTitle] = 'Digital Nomad';
Ergebnis:
+----------------+---------------+ | OccupationId | JobTitle | |----------------+---------------| | 7 | Digital Nomad | +----------------+---------------+
Die Beschränkungsdefinition
Werfen wir einen Blick auf die eigentliche Definition für chkJobTitle
Einschränkung:
SELECT Definition FROM sys.check_constraints WHERE name = 'chkJobTitle';
Ergebnis:
+-------------------------------+ | Definition | |-------------------------------| | ([JobTitle]<>'Digital Nomad') | +-------------------------------+
Diese Einschränkung besagt, dass der Wert von JobTitle Spalte darf nicht sein sei Digitaler Nomade , dennoch hat es ein digitaler Nomade geschafft, in meine Datenbank einzudringen!
Aktualisieren Sie die anstößigen Daten
Sie können die anstößigen Daten entweder aktualisieren, löschen oder in Ruhe lassen.
In diesem Beispiel verwende ich dasselbe WHERE
-Klausel zum Aktualisieren des Werts:
UPDATE [dbo].[Occupation] SET [JobTitle] = 'Unemployed' WHERE [JobTitle] = 'Digital Nomad';
Wenn ich die Prüfung jetzt erneut durchführe, ist dieser Datensatz kein Problem mehr, und nur die anderen beiden Probleme bleiben bestehen:
DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;
Ergebnis:
+------------------------+-------------------+---------------------------------------------------------+ | 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' | +------------------------+-------------------+---------------------------------------------------------+
Beispiel 2 – Verletzung von Foreign Key Constraints
In diesem Beispiel wechsle ich zu einer Datenbank, die ein paar Verletzungen von Fremdschlüsselbeschränkungen enthält.
USE Music; DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;
Ergebnis:
+----------------+---------------------+--------------------+ | Table | Constraint | Where | |----------------+---------------------+--------------------| | [dbo].[Albums] | [FK_Albums_Artists] | [ArtistId] = '123' | | [dbo].[Albums] | [FK_Albums_Artists] | [ArtistId] = '17' | +----------------+---------------------+--------------------+
In diesem Fall scheinen zwei Zeilen in den Alben Tabelle verweisen auf eine ArtistId das gibt es nicht.
Ungültige Daten finden
Auch hier können wir das
Where
verwenden Spalte, um unser WHERE
zu konstruieren Klausel. Dieses Mal füge ich beide Verstöße meinem WHERE
hinzu Klausel:
SELECT * FROM [dbo].[Albums] WHERE [ArtistId] = '123' OR [ArtistId] = '17';
Ergebnis:
+-----------+-------------+---------------+------------+-----------+ | AlbumId | AlbumName | ReleaseDate | ArtistId | GenreId | |-----------+-------------+---------------+------------+-----------| | 21 | Yo Wassup | 2019-03-12 | 17 | 3 | | 22 | Busted | 1901-05-11 | 123 | 3 | +-----------+-------------+---------------+------------+-----------+
Wir können also jetzt die beiden Zeilen sehen, die gegen die Einschränkung verstoßen (obwohl es nur die ArtistId ist Spalte, die gegen die Beschränkung verstößt).
Prüfen Sie die Primärschlüsseltabelle
Wir können den Verstoß bestätigen, indem wir die Künstler befragen Tabelle (d. h. die Tabelle, die den Primärschlüssel für diesen Fremdschlüssel enthält).
Lassen Sie uns also dieselbe Abfrage für die Artists ausführen Tabelle.
SELECT * FROM [dbo].[Artists] WHERE [ArtistId] = '123' OR [ArtistId] = '17';
Ergebnis:
(0 rows affected)
Wie erwartet ist keiner der Werte in dieser Tabelle enthalten.
Der Fremdschlüssel soll dies verhindern. Entweder wurden die ungültigen Daten in die Datenbank eingegeben, während der Fremdschlüssel deaktiviert war, oder sie wurden eingegeben, bevor der Fremdschlüssel erstellt wurde. So oder so, beim Erstellen oder Aktivieren eines Fremdschlüssels oder CHECK
Beschränkung, sollten Sie WITH CHECK
verwenden um anzugeben, dass alle vorhandenen Daten überprüft werden sollen, bevor die Einschränkung aktiviert wird.
Beispiel 3 – Nur aktivierte Beschränkungen prüfen
Wenn Sie nur die derzeit aktivierten Einschränkungen überprüfen möchten, entfernen Sie WITH ALL_CONSTRAINTS
:
USE Test; DBCC CHECKCONSTRAINTS;
Ergebnis:
+--------------------+---------------+------------------------------+ | Table | Constraint | Where | |--------------------+---------------+------------------------------| | [dbo].[Occupation] | [chkJobTitle] | [JobTitle] = 'Digital Nomad' | +--------------------+---------------+------------------------------+
Von den beiden verletzten Einschränkungen scheint also chkJobTitle ist die einzige, die aktiviert wurde.
Wir können dies weiter mit der folgenden Abfrage überprüfen:
SELECT name, is_disabled FROM sys.check_constraints WHERE name = 'chkValidEndDate' OR name = 'chkJobTitle';
Ergebnis:
+-----------------+---------------+ | name | is_disabled | |-----------------+---------------| | chkJobTitle | 0 | | chkValidEndDate | 1 | +-----------------+---------------+
Beispiel 4 – Nur Einschränkungen für eine gegebene Tabelle prüfen
Sie können den Namen einer Tabelle in Klammern hinzufügen, wenn Sie nur die Einschränkungen für diese Tabelle überprüfen möchten:
USE Test; DBCC CHECKCONSTRAINTS(ConstraintTest) WITH ALL_CONSTRAINTS;
Ergebnis:
+------------------------+-------------------+---------------------------------------------------------+ | 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' | +------------------------+-------------------+---------------------------------------------------------+
Beispiel 5 – Prüfen einer einzelnen Einschränkung
Sie können eine einzelne Einschränkung überprüfen, indem Sie ihren Namen in Klammern einschließen:
USE Test; DBCC CHECKCONSTRAINTS(chkValidEndDate);
Ergebnis:
+------------------------+-------------------+---------------------------------------------------------+ | 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' | +------------------------+-------------------+---------------------------------------------------------+
Wenn Sie eine einzelne Einschränkung angeben, wird WITH ALL_CONSTRAINTS
hat keine Auswirkung:
USE Test; DBCC CHECKCONSTRAINTS(chkValidEndDate) WITH ALL_CONSTRAINTS;
Ergebnis:
+------------------------+-------------------+---------------------------------------------------------+ | 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' | +------------------------+-------------------+---------------------------------------------------------+