U kunt de DBCC CHECKCONSTRAINTS
. uitvoeren console-opdracht om een lijst met alle schendingen van beperkingen in een SQL Server-database te retourneren.
Met deze opdracht wordt de integriteit van een opgegeven beperking of alle beperkingen op een opgegeven tabel in de huidige database gecontroleerd. Het retourneert een externe sleutel en CHECK
beperkingsschendingen die het constateert.
U kunt de ALL_CONSTRAINTS
. gebruiken optie om zowel ingeschakelde als uitgeschakelde beperkingen te controleren. Als u dit weglaat, worden alleen ingeschakelde beperkingen geretourneerd (tenzij u expliciet een beperking opgeeft om te controleren, in welk geval deze wordt geretourneerd, ongeacht of deze is ingeschakeld of uitgeschakeld).
Voorbeeld 1 – Overtreden CHECK-beperkingen
Ik heb dit voorbeeld uitgevoerd tegen een database die een aantal CHECK
. bevat beperkingsschendingen.
USE Test; DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;
Resultaat:
+------------------------+-------------------+---------------------------------------------------------+ | 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' | +------------------------+-------------------+---------------------------------------------------------+
Dit toont aan dat ik drie schendingen van beperkingen in mijn database heb.
Uitleg van de kolommen
De drie kolommen geven de volgende informatie:
- Tabel
- Naam van de tabelnaam die de schending van de beperking bevat.
- Beperking
- Naam van de beperking die wordt geschonden.
- Waar
- Kolomwaardetoewijzingen die de rij of rijen identificeren die de beperking schenden. De waarde in deze kolom kan worden gebruikt in een
WHERE
clausule van eenSELECT
statement opvragen voor rijen die de beperking schenden.
Daarom kan ik dankzij de derde kolom nu alle ongeldige gegevens vinden (en bijwerken).
Vind de ongeldige gegevens
Dus als we kijken naar de eerste rij van mijn DBCC CHECKCONSTRAINTS
resultaten, zien we dat we de gewraakte gegevens kunnen vinden met behulp van [JobTitle] = 'Digital Nomad'
in een WHERE
clausule.
Zoals dit:
SELECT * FROM [dbo].[Occupation] WHERE [JobTitle] = 'Digital Nomad';
Resultaat:
+----------------+---------------+ | OccupationId | JobTitle | |----------------+---------------| | 7 | Digital Nomad | +----------------+---------------+
De beperkingsdefinitie
Laten we eens kijken naar de daadwerkelijke definitie voor de chkJobTitle
beperking:
SELECT Definition FROM sys.check_constraints WHERE name = 'chkJobTitle';
Resultaat:
+-------------------------------+ | Definition | |-------------------------------| | ([JobTitle]<>'Digital Nomad') | +-------------------------------+
Deze beperking zegt dat de waarde van de JobTitle kolom mag niet be Digital Nomad , toch slaagde een digitale nomade er toch in om in mijn database te komen!
De beledigende gegevens bijwerken
U kunt de aanstootgevende gegevens bijwerken, verwijderen of met rust laten.
In dit voorbeeld gebruik ik dezelfde WHERE
clausule om de waarde bij te werken:
UPDATE [dbo].[Occupation] SET [JobTitle] = 'Unemployed' WHERE [JobTitle] = 'Digital Nomad';
Als ik de controle nu opnieuw uitvoer, is dat record niet langer een probleem en blijven alleen de andere twee problemen over:
DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;
Resultaat:
+------------------------+-------------------+---------------------------------------------------------+ | 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' | +------------------------+-------------------+---------------------------------------------------------+
Voorbeeld 2 – Overtreden beperkingen van buitenlandse sleutels
In dit voorbeeld schakel ik over naar een database die een aantal schendingen van externe sleutelbeperkingen bevat.
USE Music; DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;
Resultaat:
+----------------+---------------------+--------------------+ | Table | Constraint | Where | |----------------+---------------------+--------------------| | [dbo].[Albums] | [FK_Albums_Artists] | [ArtistId] = '123' | | [dbo].[Albums] | [FK_Albums_Artists] | [ArtistId] = '17' | +----------------+---------------------+--------------------+
In dit geval lijkt het erop dat twee rijen in de Albums tabel verwijzen naar een ArtistId dat bestaat niet.
Vind de ongeldige gegevens
Nogmaals, we kunnen de
Waar
. gebruiken kolom om onze WHERE
. te construeren clausule. Deze keer voeg ik beide schendingen toe aan mijn WHERE
clausule:
SELECT * FROM [dbo].[Albums] WHERE [ArtistId] = '123' OR [ArtistId] = '17';
Resultaat:
+-----------+-------------+---------------+------------+-----------+ | AlbumId | AlbumName | ReleaseDate | ArtistId | GenreId | |-----------+-------------+---------------+------------+-----------| | 21 | Yo Wassup | 2019-03-12 | 17 | 3 | | 22 | Busted | 1901-05-11 | 123 | 3 | +-----------+-------------+---------------+------------+-----------+
We kunnen nu dus de twee rijen zien die de beperking schenden (hoewel het alleen de ArtistId is kolom die de beperking schendt).
Controleer de primaire sleuteltabel
We kunnen de schending bevestigen door de Artiesten . te ondervragen tabel (d.w.z. de tabel die de primaire sleutel voor deze refererende sleutel bevat).
Dus laten we dezelfde query uitvoeren op de Artiesten tafel.
SELECT * FROM [dbo].[Artists] WHERE [ArtistId] = '123' OR [ArtistId] = '17';
Resultaat:
(0 rows affected)
Zoals verwacht, staat geen van beide waarden in die tabel.
De externe sleutel zou dit moeten voorkomen. De ongeldige gegevens zijn de database binnengekomen terwijl de externe sleutel was uitgeschakeld, of ze zijn ingevoerd voordat de externe sleutel is gemaakt. Hoe dan ook, bij het aanmaken of inschakelen van een externe sleutel of CHECK
beperking, moet u WITH CHECK
. gebruiken om aan te geven dat alle bestaande gegevens moeten worden gecontroleerd voordat de beperking wordt ingeschakeld.
Voorbeeld 3 – Alleen ingeschakelde beperkingen aanvinken
Als u alleen beperkingen wilt controleren die momenteel zijn ingeschakeld, verwijdert u WITH ALL_CONSTRAINTS
:
USE Test; DBCC CHECKCONSTRAINTS;
Resultaat:
+--------------------+---------------+------------------------------+ | Table | Constraint | Where | |--------------------+---------------+------------------------------| | [dbo].[Occupation] | [chkJobTitle] | [JobTitle] = 'Digital Nomad' | +--------------------+---------------+------------------------------+
Dus van de twee beperkingen die werden geschonden, lijkt het erop dat chkJobTitle is de enige die is ingeschakeld.
We kunnen dit verder verifiëren met de volgende vraag:
SELECT name, is_disabled FROM sys.check_constraints WHERE name = 'chkValidEndDate' OR name = 'chkJobTitle';
Resultaat:
+-----------------+---------------+ | name | is_disabled | |-----------------+---------------| | chkJobTitle | 0 | | chkValidEndDate | 1 | +-----------------+---------------+
Voorbeeld 4 – Alleen beperkingen voor een gegeven tabel aanvinken
U kunt de naam van een tabel tussen haakjes toevoegen als u alleen de beperkingen voor die tabel wilt controleren:
USE Test; DBCC CHECKCONSTRAINTS(ConstraintTest) WITH ALL_CONSTRAINTS;
Resultaat:
+------------------------+-------------------+---------------------------------------------------------+ | 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' | +------------------------+-------------------+---------------------------------------------------------+
Voorbeeld 5 – Controleer een enkele beperking
U kunt een enkele beperking controleren door de naam tussen haakjes te plaatsen:
USE Test; DBCC CHECKCONSTRAINTS(chkValidEndDate);
Resultaat:
+------------------------+-------------------+---------------------------------------------------------+ | 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' | +------------------------+-------------------+---------------------------------------------------------+
Wanneer u een enkele beperking opgeeft, wordt de WITH ALL_CONSTRAINTS
heeft geen effect:
USE Test; DBCC CHECKCONSTRAINTS(chkValidEndDate) WITH ALL_CONSTRAINTS;
Resultaat:
+------------------------+-------------------+---------------------------------------------------------+ | 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' | +------------------------+-------------------+---------------------------------------------------------+