在SQL Server的对象资源管理器中,选择和编写外键约束时,将生成以下代码。

     USE [MyTestDatabase]
     GO

     ALTER TABLE [dbo].[T2] WITH NOCHECK ADD CONSTRAINT [FK_T2_T1] FOREIGN KEY([T1ID])
     REFERENCES [dbo].[T1] ([T1ID])
     GO

     ALTER TABLE [dbo].[T2] CHECK CONSTRAINT [FK_T2_T1]
     GO


最后一条语句的目的是什么?”更改表检查约束”?它是否运行似乎无关紧要。它不会对现有的不良数据失败,也不会改变对新数据强制执行约束的情况。

谢谢!

#1 楼

它确保在创建约束后将其启用。您的ALTER TABLE语句包含WITH NOCHECK,这是说不要在创建约束时检查现有不良数据的部分。

如所写,由于WITH NOCHECK,不会针对约束检查现有数据在第一个语句中。发出第二条语句将使能针对该约束所涵盖的表的任何将来更改对约束进行检查,直到发出ALTER TABLE [dbo].[T2] NOCHECK CONSTRAINT [FK_T2_T1]为止。

语句如下:基本上是说“创建此外键约束,但不要对照现有数据进行检查。将其激活以进行数据的任何即将发生的更改。”

评论


实际上,我检查了一下,如果有错误的数据并没有什么不同,第一行或第二行都不会失败。要一次失败,他们必须看起来像这样:

–豪华
2012年9月13日20:17在

更改表[dbo]。[T2],并带有检查检查约束[FK_T2_T1]

–豪华
2012年9月13日20:18在

对。但是当您尝试运行违反约束的INSERT或UPDATE时,它将在此之后失败。如果在执行这2条语句时存在错误数据,则不会失败。

–squillman
2012年9月13日20:19在

#2 楼

您的第一条语句创建了一个禁用的约束。需要启用它并可能信任它。以下奇怪的语法将确保您的约束已启用并受信任:

ALTER TABLE YourTable
      WITH CHECK CHECK CONSTRAINT YourConstraint;


Hugo Kornelis的一篇非常好的博客文章对此进行了详细解释:您能相信您的约束