Страница документации 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
Указывает, что имя_ограничения включено или отключено. Эта опция может быть использована только с 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", столбец "помощь".
ALTER TABLE b WITH NOCHECK CHECK CONSTRAINT [My_FORIEGN_KEY]; -- enable constraint without checking
, это будет означать, что ограничение не будет проверять существующие данные, только новые входящие данные?Вы можете прочитать статью здесь: https://msdn.microsoft.com/en-us/library/ms190273.aspx
Он говорит нам: «Оптимизатор запросов не учитывает ограничения, которые определены с помощью NOCHECK. Такие ограничения игнорируются до тех пор, пока они не будут повторно включены с помощью таблицы ALTER TABLE WITH CHECK CHECK CONSTRAINT ALL '
Кроме того, рассмотрите этот поток в StackOverflow: /programming/529941/with-check-add-constraint-followed-by-check-constraint-vs-add-constraint
источник