Відповіді:
Сторінка документації MSDN про таке ALTER TABLE
пояснює:
ALTER TABLE
: змінити структуру таблиці CHECK CONSTRAINT ..
: включити обмеженняNOCHECK CONSTRAINT ..
: вимкнення обмеження WITH CHECK
: також перевірити обмеженняWITH NOCHECK
: не перевіряйте обмеженняЗ їх слів:
| [ WITH { CHECK | NOCHECK } ] { CHECK | NOCHECK } CONSTRAINT { ALL | constraint_name [ ,...n ] }
...
WITH CHECK | WITH NOCHECK
Вказує, чи дані в таблиці не підтверджені щодо нещодавно доданих або повторно включенихFOREIGN KEY
абоCHECK
обмежень . Якщо не вказано,WITH CHECK
передбачається для нових обмежень іWITH NOCHECK
передбачається для повторно включених обмежень.Якщо ви не хочете перевіряти нові
CHECK
чиFOREIGN KEY
обмеження щодо існуючих даних, використовуйтеWITH NOCHECK
. Ми не рекомендуємо робити це, за винятком рідкісних випадків. Нове обмеження буде оцінено в усіх наступних оновленнях даних. Будь-які порушення обмежень, які придушуютьсяWITH NOCHECK
при додаванні обмеження, можуть спричинити збій майбутніх оновлень, якщо вони оновлюють рядки даними, які не відповідають обмеженню.Оптимізатор запитів не враховує визначені обмеження
WITH NOCHECK
. Такі обмеження ігноруються до тих пір, поки їх не буде включено повторно за допомогоюALTER TABLE
таблиціWITH CHECK CHECK CONSTRAINT ALL
....
{ CHECK | NOCHECK } CONSTRAINT
Вказує, що ім'я constraint_ увімкнено або вимкнено. Ця опція може бути використана тільки зFOREIGN KEY
іCHECK
обмеження. КолиNOCHECK
зазначено, обмеження вимкнено, а майбутні вставки або оновлення стовпця не перевіряються щодо умов обмеження.DEFAULT
,PRIMARY KEY
іUNIQUE
обмеження неможливо відключити.
Тест у dbfiddle :
CREATE TABLE a (aid INT PRIMARY KEY);
ПОВЕРНУТИСЯ
✓
INSERT INTO a (aid) VALUES (1), (2), (3) ;
ПОВЕРНУТИСЯ
3 рядки уражені
CREATE TABLE b ( aid INT, bid INT PRIMARY KEY, CONSTRAINT [My_FORIEGN_KEY] FOREIGN KEY (aid) REFERENCES a (aid) ) ;
ПОВЕРНУТИСЯ
✓
INSERT INTO b (aid, bid) VALUES (1, 11), (1, 12), (2, 21), (3, 31) ;
ПОВЕРНУТИСЯ
Зачеплені 4 ряди
INSERT INTO b (aid, bid) VALUES (6, 61), (6, 62) ;
ПОВЕРНУТИСЯ
Msg 547 Рівень 16 Стан 0 Рядок 1 Заява INSERT суперечить обмеженню FOREIGN KEY "My_FORIEGN_KEY". Конфлікт стався в базі даних "fiddle_792fce5de09f42908c3a0f91421f3522", таблиці "dbo.a", стовпці "довідка". Msg 3621 Рівень 0 Стан 0 Рядок 1 Заява скасована.
SELECT * FROM b ;
ПОВЕРНУТИСЯ
допомога | ставка -: | -: 1 | 11 1 | 12 2 | 21 3 | 31
ALTER TABLE b NOCHECK CONSTRAINT [My_FORIEGN_KEY]; --disable
ПОВЕРНУТИСЯ
✓
INSERT INTO b (aid, bid) VALUES (4, 41), (4, 42) ;
ПОВЕРНУТИСЯ
2 рядки уражені
SELECT * FROM b ;
ПОВЕРНУТИСЯ
допомога | ставка -: | -: 1 | 11 1 | 12 2 | 21 3 | 31 4 | 41 4 | 42
ALTER TABLE b WITH NOCHECK CHECK CONSTRAINT [My_FORIEGN_KEY]; -- enable constraint without checking existing data
ПОВЕРНУТИСЯ
✓
SELECT * FROM b ;
ПОВЕРНУТИСЯ
допомога | ставка -: | -: 1 | 11 1 | 12 2 | 21 3 | 31 4 | 41 4 | 42
INSERT INTO b (aid, bid) VALUES (6, 61), (6, 62) ;
ПОВЕРНУТИСЯ
Msg 547 Рівень 16 Стан 0 Рядок 1 Заява INSERT суперечить обмеженню FOREIGN KEY "My_FORIEGN_KEY". Конфлікт стався в базі даних "fiddle_792fce5de09f42908c3a0f91421f3522", таблиці "dbo.a", стовпці "довідка". Msg 3621 Рівень 0 Стан 0 Рядок 1 Заява скасована.
SELECT * FROM b ;
ПОВЕРНУТИСЯ
допомога | ставка -: | -: 1 | 11 1 | 12 2 | 21 3 | 31 4 | 41 4 | 42
ALTER TABLE b WITH CHECK CHECK CONSTRAINT [My_FORIEGN_KEY]; -- check existing data and enable constraint
ПОВЕРНУТИСЯ
Msg 547 Рівень 16 Стан 0 Рядок 1 Заява ALTER TABLE суперечить обмеженню FOREIGN KEY "My_FORIEGN_KEY". Конфлікт стався в базі даних "fiddle_792fce5de09f42908c3a0f91421f3522", таблиці "dbo.a", стовпці "довідка".
Розгляньте читати статтю тут: https://msdn.microsoft.com/en-us/library/ms190273.aspx
Це говорить нам: "Оптимізатор запитів не враховує обмежень, визначених NOCHECK. Такі обмеження ігноруються до тих пір, поки їх не буде включено повторно за допомогою таблиці ALTER TABLE AND CHECK CHECK CONSTRAINT ALL '
Також врахуйте цю тему на StackOverflow: /programming/529941/with-check-add-constraint-followed-by-check-constraint-vs-add-constraint
ALTER TABLE b WITH NOCHECK CHECK CONSTRAINT [My_FORIEGN_KEY]; -- enable constraint without checking
, це буде означати, що обмеження не перевірятиме існуючі дані, а лише нові вхідні дані?