Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jak znaleźć wszystkie naruszenia ograniczeń w bazie danych SQL Server

Możesz uruchomić DBCC CHECKCONSTRAINTS polecenie konsoli, aby zwrócić listę wszystkich naruszeń ograniczeń w bazie danych SQL Server.

To polecenie sprawdza integralność określonego ograniczenia lub wszystkich ograniczeń w określonej tabeli w bieżącej bazie danych. Zwraca dowolny klucz obcy i CHECK znalezione naruszenia ograniczeń.

Możesz użyć ALL_CONSTRAINTS możliwość sprawdzenia zarówno włączonych, jak i wyłączonych ograniczeń. Jeśli to pominiesz, zwrócone zostaną tylko włączone ograniczenia (chyba że wyraźnie określisz ograniczenie do sprawdzenia, w którym to przypadku zostanie ono zwrócone niezależnie od tego, czy jest włączone, czy wyłączone).

Przykład 1 – Naruszone ograniczenia kontrolne

Uruchomiłem ten przykład w bazie danych, która zawiera kilka CHECK naruszenia ograniczeń.

USE Test;
DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;

Wynik:

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

To pokazuje, że mam trzy naruszenia ograniczeń w mojej bazie danych.

Wyjaśnienie kolumn

Trzy kolumny zwracają następujące informacje:

Tabela
Nazwa nazwy tabeli, która zawiera naruszenie ograniczenia.
Ograniczenie
Nazwa ograniczenia, które zostało naruszone.
Gdzie
Przypisania wartości kolumn, które identyfikują wiersz lub wiersze naruszające ograniczenie. Wartość w tej kolumnie może być użyta w WHERE klauzula SELECT instrukcja pytająca o wiersze, które naruszają ograniczenie.

Dlatego dzięki trzeciej kolumnie mogę teraz znaleźć (i zaktualizować) wszystkie nieprawidłowe dane.

Znajdź nieprawidłowe dane

Więc jeśli spojrzymy na pierwszy wiersz z moich DBCC CHECKCONSTRAINTS wyniki, widzimy, że możemy znaleźć obraźliwe dane, używając [JobTitle] = 'Digital Nomad' w WHERE klauzula.

Tak:

SELECT *
FROM [dbo].[Occupation]
WHERE [JobTitle] = 'Digital Nomad';

Wynik:

+----------------+---------------+
| OccupationId   | JobTitle      |
|----------------+---------------|
| 7              | Digital Nomad |
+----------------+---------------+

Definicja ograniczeń

Rzućmy okiem na rzeczywistą definicję chkJobTitle ograniczenie:

SELECT Definition 
FROM sys.check_constraints
WHERE name = 'chkJobTitle';

Wynik:

+-------------------------------+
| Definition                    |
|-------------------------------|
| ([JobTitle]<>'Digital Nomad') |
+-------------------------------+

To ograniczenie mówi, że wartość JobTitle kolumna nie być cyfrowym nomadem , a mimo to cyfrowy nomada wciąż zdołał dostać się do mojej bazy danych!

Zaktualizuj naruszające dane

Możesz zaktualizować naruszające dane, usunąć je lub pozostawić w spokoju.

W tym przykładzie używam tego samego WHERE klauzula aktualizująca wartość:

UPDATE [dbo].[Occupation]
SET [JobTitle] = 'Unemployed'
WHERE [JobTitle] = 'Digital Nomad';

Teraz, jeśli ponownie sprawdzę, ten rekord nie będzie już problemem i pozostaną tylko dwa pozostałe:

DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;

Wynik:

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

Przykład 2 – Naruszone ograniczenia klucza obcego

W tym przykładzie przełączam się na bazę danych, która zawiera kilka naruszeń ograniczeń kluczy obcych.

USE Music;
DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;

Wynik:

+----------------+---------------------+--------------------+
| Table          | Constraint          | Where              |
|----------------+---------------------+--------------------|
| [dbo].[Albums] | [FK_Albums_Artists] | [ArtistId] = '123' |
| [dbo].[Albums] | [FK_Albums_Artists] | [ArtistId] = '17'  |
+----------------+---------------------+--------------------+

W tym przypadku wygląda na to, że dwa wiersze w Albumach tabela odwołuje się do ArtistId to nie istnieje.

Znajdź nieprawidłowe dane

Ponownie możemy użyć Gdzie kolumna do skonstruowania naszego WHERE klauzula. Tym razem dodam oba naruszenia do mojego WHERE klauzula:

SELECT *
FROM [dbo].[Albums]
WHERE [ArtistId] = '123' OR [ArtistId] = '17';

Wynik:

+-----------+-------------+---------------+------------+-----------+
| AlbumId   | AlbumName   | ReleaseDate   | ArtistId   | GenreId   |
|-----------+-------------+---------------+------------+-----------|
| 21        | Yo Wassup   | 2019-03-12    | 17         | 3         |
| 22        | Busted      | 1901-05-11    | 123        | 3         |
+-----------+-------------+---------------+------------+-----------+

Możemy więc teraz zobaczyć dwa wiersze, które naruszają ograniczenie (chociaż jest to tylko ArtistId kolumna, która narusza ograniczenie).

Sprawdź tabelę kluczy podstawowych

Możemy potwierdzić naruszenie, wysyłając zapytanie do Artystów tabela (tj. tabela zawierająca klucz podstawowy dla tego klucza obcego).

Uruchommy więc to samo zapytanie dla Wykonawców tabela.

SELECT *
FROM [dbo].[Artists]
WHERE [ArtistId] = '123' OR [ArtistId] = '17';

Wynik:

(0 rows affected)

Zgodnie z oczekiwaniami w tej tabeli nie ma żadnej wartości.

Klucz obcy ma temu zapobiec. Albo nieprawidłowe dane zostały wprowadzone do bazy danych, gdy klucz obcy był wyłączony, albo zostały wprowadzone przed utworzeniem klucza obcego. Tak czy inaczej, podczas tworzenia lub włączania klucza obcego lub CHECK ograniczeniem, powinieneś użyć WITH CHECK aby określić, że wszystkie istniejące dane powinny być sprawdzone przed włączeniem ograniczenia.

Przykład 3 – Sprawdź tylko włączone ograniczenia

Jeśli chcesz tylko sprawdzić ograniczenia, które są aktualnie włączone, usuń WITH ALL_CONSTRAINTS :

USE Test;
DBCC CHECKCONSTRAINTS;

Wynik:

+--------------------+---------------+------------------------------+
| Table              | Constraint    | Where                        |
|--------------------+---------------+------------------------------|
| [dbo].[Occupation] | [chkJobTitle] | [JobTitle] = 'Digital Nomad' |
+--------------------+---------------+------------------------------+

Wygląda więc na to, że spośród dwóch naruszonych ograniczeń chkJobTitle jest jedynym, który został włączony.

Możemy to dodatkowo zweryfikować za pomocą następującego zapytania:

SELECT 
  name,
  is_disabled
FROM sys.check_constraints
WHERE name = 'chkValidEndDate' OR name = 'chkJobTitle';

Wynik:

+-----------------+---------------+
| name            | is_disabled   |
|-----------------+---------------|
| chkJobTitle     | 0             |
| chkValidEndDate | 1             |
+-----------------+---------------+

Przykład 4 – Sprawdź tylko ograniczenia dla danej tabeli

Możesz dodać nazwę tabeli w nawiasach, jeśli chcesz tylko sprawdzić ograniczenia dla tej tabeli:

USE Test;
DBCC CHECKCONSTRAINTS(ConstraintTest) WITH ALL_CONSTRAINTS;

Wynik:

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

Przykład 5 – Sprawdź pojedyncze wiązanie

Możesz sprawdzić pojedyncze ograniczenie, umieszczając jego nazwę w nawiasach:

USE Test;
DBCC CHECKCONSTRAINTS(chkValidEndDate);

Wynik:

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

Gdy określisz pojedyncze ograniczenie, WITH ALL_CONSTRAINTS nie ma wpływu:

USE Test;
DBCC CHECKCONSTRAINTS(chkValidEndDate) WITH ALL_CONSTRAINTS;

Wynik:

+------------------------+-------------------+---------------------------------------------------------+
| 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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak przyspieszyć wstawianie zbiorcze do MS SQL Server za pomocą pyodbc?

  2. Replikacja bazy danych SQL Server

  3. Jak ISNUMERIC() działa w SQL Server

  4. SQL Server POKAŻ TABELI odpowiednik

  5. Jak zaktualizować wiersze o losową datę?