Answers:
有关的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
table 重新启用这些约束之前,将忽略这些约束WITH CHECK CHECK CONSTRAINT ALL
。...
{ CHECK | NOCHECK } CONSTRAINT
指定启用或禁用constraint_name。此选项只能与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) ;
走
消息547级别16状态0线路1 INSERT语句与FOREIGN KEY约束“ My_FORIEGN_KEY”冲突。在数据库“ fiddle_792fce5de09f42908c3a0f91421f3522”的表“ dbo.a”的“ aid”列中发生了冲突。 消息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) ;
走
消息547级别16状态0线路1 INSERT语句与FOREIGN KEY约束“ My_FORIEGN_KEY”冲突。在数据库“ fiddle_792fce5de09f42908c3a0f91421f3522”的表“ dbo.a”的“ aid”列中发生了冲突。 消息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
走
消息547级别16状态0线路1 ALTER TABLE语句与FOREIGN KEY约束“ My_FORIEGN_KEY”冲突。在数据库“ fiddle_792fce5de09f42908c3a0f91421f3522”的表“ dbo.a”的“ aid”列中发生了冲突。
考虑在这里阅读文章:https : //msdn.microsoft.com/en-us/library/ms190273.aspx
它告诉我们:“查询优化器不考虑使用NOCHECK定义的约束。在使用ALTER TABLE table WITH CHECK CHECK CONSTRAINT ALL'重新启用它们之前,将忽略这些约束。
另外,考虑一下StackOverflow上的线程:https ://stackoverflow.com/questions/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
,这是否意味着约束将不检查现有数据,仅检查新的传入数据?