sql >> Database >  >> RDS >> Sqlserver

Hoe u alle schendingen van beperkingen in een SQL Server-database kunt vinden

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

  1. Hoe de tijdzoneregio voor JDBC Connection in te stellen en te voorkomen dat de SqlException-tijdzoneregio niet wordt gevonden?

  2. WEEKDAY() Voorbeelden – MySQL

  3. Oracle Database 21c

  4. Blob in Oracle-database invoegen met C#