sql >> Database teknologi >  >> RDS >> Sqlserver

Sådan finder du alle overtrædelser af begrænsninger i en SQL Server-database

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 en SELECT 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' |
+------------------------+-------------------+---------------------------------------------------------+

  1. Forespørgselsoptimering i PostgreSQL. FORKLAR Grundlæggende – Del 2

  2. Den hurtigste måde at kontrollere, om nogle poster i en databasetabel?

  3. Sådan fungerer SQLite Trim()

  4. Sådan bootstrap MySQL eller MariaDB Galera Cluster - Opdateret