Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Как да намерите всички нарушения на ограниченията в база данни на SQL Server

Можете да стартирате DBCC CHECKCONSTRAINTS console команда за връщане на списък с всички нарушения на ограниченията в база данни на SQL Server.

Тази команда проверява целостта на определено ограничение или всички ограничения на определена таблица в текущата база данни. Връща всеки външен ключ и CHECK нарушения на ограниченията, които установи.

Можете да използвате ALL_CONSTRAINTS опция за проверка на разрешените и деактивираните ограничения. Ако пропуснете това, тогава се връщат само разрешени ограничения (освен ако не посочите изрично ограничение за проверка, в който случай то ще бъде върнато независимо дали е активирано или деактивирано).

Пример 1 – Нарушени ограничения на CHECK

Изпълних този пример срещу база данни, която съдържа CHECK нарушения на ограниченията.

USE Test;
DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;

Резултат:

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

Това показва, че имам три нарушения на ограниченията в моята база данни.

Обяснение на колоните

Трите колони връщат следната информация:

Таблица
Име на името на таблицата, което съдържа нарушението на ограничението.
Ограничение
Име на ограничението, което е нарушено.
Къде
Присвоявания на стойности на колони, които идентифицират реда или редовете, нарушаващи ограничението. Стойността в тази колона може да се използва в WHERE клауза на SELECT заявка на заявка за редове, които нарушават ограничението.

Ето защо, благодарение на третата колона, вече мога да намеря (и актуализирам) всички невалидни данни.

Намерете невалидните данни

Така че, ако погледнем първия ред от моите DBCC CHECKCONSTRAINTS резултати, виждаме, че можем да намерим неправомерните данни, като използваме [JobTitle] = 'Digital Nomad' в WHERE клауза.

Като това:

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

Резултат:

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

Дефиницията на ограничението

Нека да разгледаме действителната дефиниция за chkJobTitle ограничение:

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

Резултат:

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

Това ограничение казва, че стойността на JobTitle колона трябва не бъде Digital Nomad , но дигитален номад все пак успя да влезе в моята база данни!

Актуализирайте данните за нарушение

Можете или да актуализирате нарушителните данни, да ги изтриете или да ги оставите на мира.

В този пример използвам същия WHERE клауза за актуализиране на стойността:

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

Сега, ако пусна проверката отново, този запис вече не е проблем и остават само другите два проблема:

DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;

Резултат:

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

Пример 2 – Нарушени ограничения на външния ключ

В този пример преминавам към база данни, която съдържа няколко нарушения на ограниченията на външния ключ.

USE Music;
DBCC CHECKCONSTRAINTS WITH ALL_CONSTRAINTS;

Резултат:

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

В този случай изглежда, че два реда в Албуми таблицата препраща към Идентификатор на изпълнител това не съществува.

Намерете невалидните данни

Отново можем да използваме Къде колона, за да изградим нашия WHERE клауза. Този път ще добавя и двете нарушения към моя WHERE клауза:

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

Резултат:

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

Така че вече можем да видим двата реда, които нарушават ограничението (въпреки че това е само ArtistId колона, която нарушава ограничението).

Проверете таблицата с първични ключове

Можем да потвърдим нарушението, като отправим запитване към Изпълнители таблица (т.е. таблицата, която съдържа първичния ключ за този външен ключ).

Така че нека изпълним същата заявка срещу Изпълнители таблица.

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

Резултат:

(0 rows affected)

Както се очаква, нито една от стойностите не е в тази таблица.

Външният ключ трябва да предотврати това да се случи. Или невалидните данни са влезли в базата данни, докато външният ключ е бил деактивиран, или са въведени преди създаването на външния ключ. Така или иначе, когато създавате или разрешавате външен ключ или CHECK ограничение, трябва да използвате WITH CHECK за да посочите, че всички съществуващи данни трябва да бъдат проверени, преди да разрешите ограничението.

Пример 3 – Проверете само разрешените ограничения

Ако искате да проверите само ограниченията, които в момента са активирани, премахнете WITH ALL_CONSTRAINTS :

USE Test;
DBCC CHECKCONSTRAINTS;

Резултат:

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

Така че от двете ограничения, които бяха нарушени, изглежда, че chkJobTitle е единствената, която е активирана.

Можем допълнително да проверим това със следната заявка:

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

Резултат:

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

Пример 4 – Проверете само ограниченията за дадена таблица

Можете да добавите името на таблица в скоби, ако искате да проверите само ограниченията за тази таблица:

USE Test;
DBCC CHECKCONSTRAINTS(ConstraintTest) WITH ALL_CONSTRAINTS;

Резултат:

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

Пример 5 – Проверка на едно ограничение

Можете да проверите едно ограничение, като поставите името му в скоби:

USE Test;
DBCC CHECKCONSTRAINTS(chkValidEndDate);

Резултат:

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

Когато посочите едно ограничение, WITH ALL_CONSTRAINTS няма ефект:

USE Test;
DBCC CHECKCONSTRAINTS(chkValidEndDate) WITH ALL_CONSTRAINTS;

Резултат:

+------------------------+-------------------+---------------------------------------------------------+
| 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. Намерете низ, като потърсите всички таблици в SQL Server

  2. COT() Примери в SQL Server

  3. Използване на променлива в SQL израза LIKE

  4. Кой е най-добрият начин за създаване и попълване на таблица с числа?

  5. Присъединяването на множество таблици връща стойност NULL