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