Сгенерированный скрипт использует NOCHECK, поэтому ограничение всегда будет создано, даже если значения в таблице не соответствуют. Это лучше для автоматически сгенерированного сценария, так как он гарантирует, что схема базы данных будет создана или изменена правильно.
Сначала я подумал, что второй оператор в сгенерированном скрипте должен гарантировать, что оптимизатор запросов рассмотрит ограничение. (См. Ссылку ниже.) Однако при дальнейшем расследовании кажется, что второе утверждение не имеет никакого эффекта - см. Мой второй ответ.
Когда вы делаете это вручную, используя WITH CHECK, вы можете сразу увидеть, что утверждение не выполнено, и предпримите корректирующие действия. Затем запустите инструкцию еще раз.
Если вы используете опцию WITH NOCHECK, вы можете не заметить, что данные недействительны. Лично я всегда использую WITH CHECK, когда ALTER TABLE добавляет ограничения. Также Books Online говорит, что использование WITH NOCHECK не рекомендуется, за исключением редких случаев - см. Ссылки ниже.
Чтобы продемонстрировать разницу, давайте сначала создадим таблицу и введем некоторые значения.
CREATE TABLE dbo.T
(
id int NOT NULL IDENTITY(1,1),
[column] nchar(1) NOT NULL
);
INSERT INTO dbo.T ([column])
VALUES (N'A'), (N'B'), (N'C'), (N'E');
Попробуйте изменить таблицу и добавить ограничение, указав WITH CHECK. Это не удается, потому что некоторые данные в таблице не соответствуют ограничению.
ALTER TABLE dbo.T
WITH CHECK
ADD CONSTRAINT CK_Column CHECK ([column] IN (N'A', N'B', N'C', N'D'));
Давайте посмотрим, если ограничение было создано, с помощью представления sys.check_constraints системы каталога. Это показывает, что ограничение не создано.
SELECT *
FROM sys.check_constraints
WHERE [parent_object_id] = OBJECT_ID(N'dbo.T');
Попробуйте еще раз, на этот раз указав С NOCHECK. На этот раз он завершается успешно. Однако нет предупреждений о том, что данные в таблице недействительны, что может быть нежелательным.
ALTER TABLE dbo.T
WITH NOCHECK
ADD CONSTRAINT CK_Column CHECK ([column] IN (N'A', N'B', N'C', N'D'));
И мы можем проверить, что ограничение проверки было создано.
См Books Online> ALTER TABLE (Transact-SQL): https://msdn.microsoft.com/en-GB/library/ms190273.aspx> WITH CHECK | С NOCHECK
Если вы не хотите проверять новые ограничения CHECK или FOREIGN KEY для существующих данных, используйте WITH NOCHECK. Мы не рекомендуем это делать, за исключением редких случаев. Новое ограничение будет оцениваться во всех последующих обновлениях данных. Любые нарушения ограничений, которые подавляются WITH NOCHECK при добавлении ограничения, могут привести к сбою будущих обновлений, если они обновляют строки данными, которые не соответствуют ограничению.
Причина второго автоматически генерируемый оператор показал здесь:
оптимизатор запросов не учитывает ограничения, которые определяются с NOCHECK. Такие ограничения игнорируются до тех пор, пока они не будут повторно включены, используя таблицу ALTER TABLE WITH CHECK CHECK CONSTRAINT ALL.