Du kan køre DBCC CHECKCONSTRAINTS
console-kommando for at returnere en liste over alle overtrædelser af begrænsninger i en SQL Server-database.
Denne kommando kontrollerer integriteten af en specificeret begrænsning eller alle begrænsninger på en specificeret tabel i den aktuelle database. Det returnerer enhver fremmed nøgle og CHECK
begrænsninger, som den finder.
Du kan bruge ALL_CONSTRAINTS
mulighed for at kontrollere både aktiverede og deaktiverede begrænsninger. Hvis du udelader dette, returneres kun aktiverede begrænsninger (medmindre du udtrykkeligt angiver en begrænsning, der skal kontrolleres, i hvilket tilfælde den returneres, uanset om den er aktiveret eller deaktiveret).
Eksempel 1 – Overtrådt CHECK-begrænsninger
Jeg kørte dette eksempel mod en database, der indeholder nogle CHECK
overtrædelser af begrænsninger.
USE Test; DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;
Resultat:
+------------------------+-------------------+---------------------------------------------------------+ | 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' | +------------------------+-------------------+---------------------------------------------------------+
Dette viser, at jeg har tre overtrædelser af begrænsninger i min database.
Forklaring af kolonnerne
De tre kolonner returnerer følgende information:
- Tabel
- Navnet på det tabelnavn, der indeholder begrænsningsovertrædelsen.
- Begrænsning
- Navn på den begrænsning, der er overtrådt.
- Hvor
- Kolonneværditildelinger, der identificerer den eller de rækker, der overtræder begrænsningen. Værdien i denne kolonne kan bruges i en
WHERE
klausul af enSELECT
sætning, der forespørger efter rækker, der overtræder begrænsningen.
Derfor kan jeg, takket være den tredje kolonne, nu finde (og opdatere) alle ugyldige data.
Find de ugyldige data
Så hvis vi ser på den første række fra min DBCC CHECKCONSTRAINTS
resultater, ser vi, at vi kan finde de stødende data ved at bruge [JobTitle] = 'Digital Nomad'
i en WHERE
klausul.
Sådan:
SELECT * FROM [dbo].[Occupation] WHERE [JobTitle] = 'Digital Nomad';
Resultat:
+----------------+---------------+ | OccupationId | JobTitle | |----------------+---------------| | 7 | Digital Nomad | +----------------+---------------+
Begrænset definition
Lad os tage et kig på den faktiske definition for chkJobTitle
begrænsning:
SELECT Definition FROM sys.check_constraints WHERE name = 'chkJobTitle';
Resultat:
+-------------------------------+ | Definition | |-------------------------------| | ([JobTitle]<>'Digital Nomad') | +-------------------------------+
Denne begrænsning siger, at værdien af JobTitle kolonne må ikke være Digital Nomade , men alligevel lykkedes det en digital nomade at komme ind i min database!
Opdater de krænkende data
Du kan enten opdatere de stødende data, slette dem eller lade dem ligge.
I dette eksempel bruger jeg den samme WHERE
klausul for at opdatere værdien:
UPDATE [dbo].[Occupation] SET [JobTitle] = 'Unemployed' WHERE [JobTitle] = 'Digital Nomad';
Hvis jeg nu kører kontrollen igen, er den post ikke længere et problem, og kun de to andre problemer er tilbage:
DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;
Resultat:
+------------------------+-------------------+---------------------------------------------------------+ | 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' | +------------------------+-------------------+---------------------------------------------------------+
Eksempel 2 – Overtrådt udenlandske nøglebegrænsninger
I dette eksempel skifter jeg til en database, der indeholder et par overtrædelser af fremmednøgler.
USE Music; DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;
Resultat:
+----------------+---------------------+--------------------+ | Table | Constraint | Where | |----------------+---------------------+--------------------| | [dbo].[Albums] | [FK_Albums_Artists] | [ArtistId] = '123' | | [dbo].[Albums] | [FK_Albums_Artists] | [ArtistId] = '17' | +----------------+---------------------+--------------------+
I dette tilfælde ser det ud til, at to rækker i Album tabel refererer til et ArtistId det eksisterer ikke.
Find de ugyldige data
Igen kan vi bruge
Hvor
kolonne for at konstruere vores WHERE
klausul. Denne gang vil jeg tilføje begge overtrædelser til min WHERE
klausul:
SELECT * FROM [dbo].[Albums] WHERE [ArtistId] = '123' OR [ArtistId] = '17';
Resultat:
+-----------+-------------+---------------+------------+-----------+ | AlbumId | AlbumName | ReleaseDate | ArtistId | GenreId | |-----------+-------------+---------------+------------+-----------| | 21 | Yo Wassup | 2019-03-12 | 17 | 3 | | 22 | Busted | 1901-05-11 | 123 | 3 | +-----------+-------------+---------------+------------+-----------+
Så vi kan nu se de to rækker, der overtræder begrænsningen (selvom det kun er ArtistId kolonne, der overtræder begrænsningen).
Tjek den primære nøgletabel
Vi kan bekræfte overtrædelsen ved at forespørge Kunstnerne tabel (dvs. den tabel, der indeholder den primære nøgle til denne fremmednøgle).
Så lad os køre den samme forespørgsel mod Kunstnerne tabel.
SELECT * FROM [dbo].[Artists] WHERE [ArtistId] = '123' OR [ArtistId] = '17';
Resultat:
(0 rows affected)
Som forventet er ingen af værdierne i den tabel.
Den fremmede nøgle skal forhindre dette i at ske. Enten kom de ugyldige data ind i databasen, mens den fremmede nøgle var deaktiveret, eller også blev de indtastet, før den fremmede nøgle blev oprettet. Uanset hvad, når du opretter eller aktiverer en fremmednøgle eller CHECK
begrænsning, skal du bruge WITH CHECK
for at angive, at alle eksisterende data skal kontrolleres, før begrænsningen aktiveres.
Eksempel 3 – Marker kun aktiverede begrænsninger
Hvis du kun vil kontrollere begrænsninger, der i øjeblikket er aktiveret, skal du fjerne WITH ALL_CONSTRAINTS
:
USE Test; DBCC CHECKCONSTRAINTS;
Resultat:
+--------------------+---------------+------------------------------+ | Table | Constraint | Where | |--------------------+---------------+------------------------------| | [dbo].[Occupation] | [chkJobTitle] | [JobTitle] = 'Digital Nomad' | +--------------------+---------------+------------------------------+
Så ud af de to begrænsninger, der blev overtrådt, ser det ud til, at chkJobTitle er den eneste, der var aktiveret.
Vi kan bekræfte dette yderligere med følgende forespørgsel:
SELECT name, is_disabled FROM sys.check_constraints WHERE name = 'chkValidEndDate' OR name = 'chkJobTitle';
Resultat:
+-----------------+---------------+ | name | is_disabled | |-----------------+---------------| | chkJobTitle | 0 | | chkValidEndDate | 1 | +-----------------+---------------+
Eksempel 4 – Kontroller kun begrænsninger for en given tabel
Du kan tilføje navnet på en tabel i parentes, hvis du kun vil kontrollere begrænsningerne for den tabel:
USE Test; DBCC CHECKCONSTRAINTS(ConstraintTest) WITH ALL_CONSTRAINTS;
Resultat:
+------------------------+-------------------+---------------------------------------------------------+ | 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' | +------------------------+-------------------+---------------------------------------------------------+
Eksempel 5 – Tjek en enkelt begrænsning
Du kan kontrollere en enkelt begrænsning ved at omslutte dens navn i parenteser:
USE Test; DBCC CHECKCONSTRAINTS(chkValidEndDate);
Resultat:
+------------------------+-------------------+---------------------------------------------------------+ | 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' | +------------------------+-------------------+---------------------------------------------------------+
Når du angiver en enkelt begrænsning, vises WITH ALL_CONSTRAINTS
har ingen effekt:
USE Test; DBCC CHECKCONSTRAINTS(chkValidEndDate) WITH ALL_CONSTRAINTS;
Resultat:
+------------------------+-------------------+---------------------------------------------------------+ | 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' | +------------------------+-------------------+---------------------------------------------------------+