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

Как да активирате ограничение на външния ключ в SQL Server (примери за T-SQL)

Ако имате ограничение за външен ключ в SQL Server, което в момента е деактивирано, можете да използвате кода по-долу, за да го активирате отново.

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

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

Пример 1 – Активиране на ограничение с помощта на WITH CHECK

Това е препоръчителният метод (освен ако нямате конкретна причина да не го използвате).

Ето пример за активиране на ограничение за външен ключ, наречено FK_Albums_Artists :

ALTER TABLE Albums 
WITH CHECK CHECK CONSTRAINT FK_Albums_Artists; 

Тук изрично посочвам WITH CHECK , което казва на SQL Server да провери съществуващите данни, преди да разреши ограничението. Ако някакви данни нарушават ограничението, ограничението няма да бъде активирано и ще получите грешка.

Това е добре, защото налага референтната цялост.

Когато създавате ново ограничение за външен ключ, това е настройката по подразбиране. Когато обаче активирате съществуващо ограничение (както правим тук), то не настройката по подразбиране.

Пример 2 – Активиране на ограничение с помощта на WITH NOCHECK

В този пример ограничението е активирано без проверка на съществуващите данни:

ALTER TABLE Albums 
WITH NOCHECK CHECK CONSTRAINT FK_Albums_Artists;

Тук изрично заявявам WITH NOCHECK , което казва на SQL Server да не проверява съществуващите данни. Това означава, че ограничението ще бъде активирано дори ако таблицата вече съдържа данни, които нарушават ограничението.

Това е настройката по подразбиране, когато активирате ограничение (но не и когато създавате такова).

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

Въпреки това, все още има рискове, свързани с това. Ето какво има да каже Microsoft за това:

Не препоръчваме да правите това, освен в редки случаи. Новото ограничение се оценява във всички по-късни актуализации на данни. Всички нарушения на ограниченията, които са потиснати от WITH NOCHECK когато се добави ограничението, може да доведе до неуспешни бъдещи актуализации, ако актуализират редове с данни, които не следват ограничението.

Така че използвайки WITH NOCHECK може потенциално да причини проблеми по-късно.

Пример 3 – Активиране на ограничение с помощта на опцията по подразбиране

Ето пример за използване на опцията по подразбиране:

ALTER TABLE Albums 
CHECK CONSTRAINT FK_Albums_Artists;

Този пример е еквивалент на предишния пример. Тъй като не посочих дали да проверя или не, SQL Server приема, че искам WITH NOCHECK .

Така че не забравяйте изрично да посочите WITH CHECK ако искате да избегнете проблеми с референтната цялост.

Използването на WITH NOCHECK премахва доверието

Когато активирате ограничение, като използвате (по подразбиране) WITH NOCHECK , едно следствие, което трябва да знаете, е, че SQL Server вече няма да се доверява на това ограничение. Той го маркира като недоверен. Всъщност той вече е маркиран като недоверен, когато деактивирате ограничението.

SQL Server има is_not_trusted флаг, който задава на 1 когато деактивирате ограничение за външен ключ (което означава, че не е доверено) и единственият начин да го зададете на 0 (доверен) е да посочите WITH CHECK при повторно активиране на ограничението. От друга страна, с помощта на WITH NOCHECK просто го активира, без да проверява съществуващите данни.

С помощта на WITH CHECK , гарантирате, че ограничението проверява всички съществуващи данни, преди да бъде активирано. Единственият начин да бъде активиран е, ако всички съществуващи данни отговарят на ограничението. След като провери всички съществуващи данни, на ограничението може да се вярва.

Пример 4 – Проверете състоянието на доверен/деактивиран

Можете да проверите състоянието на доверени и деактивирани, като потърсите sys.foreign_keys системен изглед.

Като това:

SELECT 
  name AS 'Constraint',
  is_disabled,
  is_not_trusted
FROM sys.foreign_keys;

Резултат:

+-------------------+---------------+------------------+
| Constraint        | is_disabled   | is_not_trusted   |
|-------------------+---------------+------------------|
| FK_Albums_Artists | 0             | 1                |
| FK_Albums_Genres  | 0             | 0                |
+-------------------+---------------+------------------+

Това ми казва, че ограничението, което активирах в предишния пример ( FK_Albums_Artists ) не се вярва.

Това е така, защото го активирах с настройката по подразбиране, която е WITH NOCHECK .

Ако го активирам отново с помощта на WITH CHECK , ето какво се случва:

ALTER TABLE Albums 
WITH CHECK CHECK CONSTRAINT FK_Albums_Artists;

SELECT 
  name AS 'Constraint',
  is_disabled,
  is_not_trusted
FROM sys.foreign_keys;

Резултат:

+-------------------+---------------+------------------+
| Constraint        | is_disabled   | is_not_trusted   |
|-------------------+---------------+------------------|
| FK_Albums_Artists | 0             | 0                |
| FK_Albums_Genres  | 0             | 0                |
+-------------------+---------------+------------------+

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

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Използване на резултата от израз (например извикване на функция) в списък с параметри на запомнени процедури?

  2. Запитване на данни чрез обединяване на две таблици в две бази данни на различни сървъри

  3. Месеци между две дати

  4. Получаване на връщаната стойност от JDBC MSSQL

  5. Вземете броя на неуспешните опити за влизане поради грешна парола в SQL Server (T-SQL)