mat*_*ewb 5 sql-server constraint ssms sql-server-2014 check-constraints
我创建了一个带有外键约束的表。当我通过 SSMS 生成表创建脚本时,它会创建以下代码:
ALTER TABLE [dbo].[MainTable] WITH CHECK ADD CONSTRAINT [FK_MainTable_ForeignKeyTable] FOREIGN KEY([FK_Field])
REFERENCES [dbo].[ForeignKeyTable] ([PK_Field])
GO
ALTER TABLE [dbo].[MainTable] CHECK CONSTRAINT [FK_MainTable_ForeignKeyTable]
GO
Run Code Online (Sandbox Code Playgroud)
由于第一个语句创建了 WITH CHECK 约束,这是否会使第二个语句变得多余?如果不是,那么 CHECK CONSTRAINT 完成了 WITH CHECK 没有完成的任务是什么?
我看到了ALTER TABLE CHECK CONSTRAINT,但在这种情况下,SSMS 正在生成第一个语句 WITH NOCHECK,所以有两个语句是有意义的。
第一个语句更改表以添加约束。第二条语句启用或禁用将来插入或更新的约束。
\n\n因此,ALTER TABLE ... CHECK CONSTRAINT ...
启用对未来插入/更新的约束。如果指定ALTER TABLE ... NOCHECK CONSTRAINT ...
,则会禁用约束,从而即使外键引用的表中的列不包含匹配值,也允许将来的插入和更新成功。您可以通过此示例了解同时存在这两个语句的实用性:
USE tempdb;\n\nIF OBJECT_ID(N'dbo.b', N'U') IS NOT NULL\nDROP TABLE dbo.b;\nIF OBJECT_ID(N'dbo.a', N'U') IS NOT NULL\nDROP TABLE dbo.a;\n\nCREATE TABLE dbo.a\n(\n a_ID int NOT NULL\n CONSTRAINT a_primary_key\n PRIMARY KEY\n CLUSTERED\n , SomeData varchar(10) NOT NULL\n) ON [PRIMARY];\n\nINSERT INTO dbo.a (a_ID, SomeData)\nVALUES (1, 'aaaa')\n , (2, 'bbbb')\n , (3, 'cccc');\n\nCREATE TABLE dbo.b\n(\n b_ID int NOT NULL\n CONSTRAINT b_primary_key\n PRIMARY KEY\n CLUSTERED\n , SomeData varchar(10) NOT NULL\n , a_ID int NOT NULL\n) ON [PRIMARY];\n\nINSERT INTO dbo.b (b_ID, SomeData, a_ID)\nVALUES (49, 'dddd', 1)\n , (50, 'eeee', 2)\n , (51, 'ffff', 3);\n
Run Code Online (Sandbox Code Playgroud)\n\n因此,我们创建了两个没有定义关系的表。后来,我们决定要设计关系,因此我们在 中添加一个外键来dbo.b
引用 中的主键列dbo.a
。我们希望检查现有行的有效性,但不关心将来可能添加的新行1。
ALTER TABLE dbo.b \nWITH CHECK\nADD CONSTRAINT b_a_foreign_key\nFOREIGN KEY (a_ID)\nREFERENCES a(a_ID);\n\nALTER TABLE dbo.b \nNOCHECK CONSTRAINT b_a_foreign_key;\n
Run Code Online (Sandbox Code Playgroud)\n\n都好。已验证现有行,并且不会根据外键验证新行:
\n\nINSERT INTO dbo.b (b_ID, SomeData, a_ID)\nVALUES (52, 'gggg', 4);\n
Run Code Online (Sandbox Code Playgroud)\n\n表内容:
\n\nSELECT *\nFROM dbo.b\n LEFT JOIN dbo.a ON b.a_ID = a.a_ID\n
Run Code Online (Sandbox Code Playgroud)\n\n结果:
\n\n\xe2\x95\x94\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa6\xe2 \x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95 \x90\xe2\x95\x90\xe2\x95\xa6\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90 \xe2\x95\xa6\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa6\xe2 \x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95 \x90\xe2\x95\x90\xe2\x95\x97\n\xe2\x95\x91 b_ID \xe2\x95\x91 SomeData \xe2\x95\x91 a_ID \xe2\x95\x91 a_ID \xe2\x95\x91一些数据\xe2\x95\x91\n\xe2\x95\xa0\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\ x90\xe2\x95\xac\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\ xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xac\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\ x95\x90\xe2\x95\x90\xe2\x95\xac\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\ x90\xe2\x95\xac\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\ xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa3\n\xe2\x95\x91 49 \xe2\x95\x91 dddd \xe2\x95\x91 1 \xe2\x95 \x91 1 \xe2\x95\x91 aaaa \xe2\x95\x91\n\xe2\x95\x91 50 \xe2\x95\x91 eeee \xe2\x95\x91 2 \xe2\x95\x91 2 \xe2\x95 \x91 bbbb \xe2\x95\x91\n\xe2\x95\x91 51 \xe2\x95\x91 ffff \xe2\x95\x91 3 \xe2\x95\x91 3 \xe2\x95\x91 cccc \xe2\x95 \x91\n\xe2\x95\x91 52 \xe2\x95\x91 gggg \xe2\x95\x91 4 \xe2\x95\x91 NULL \xe2\x95\x91 NULL \xe2\x95\x91 <-- 疯狂的东西\n\xe2\x95\x9a\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa9 \xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2 \x95\x90\xe2\x95\x90\xe2\x95\xa9\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95 \x90\xe2\x95\xa9\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa9 \xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2 \x95\x90\xe2\x95\x90\xe2\x95\x9d\n\n\n
因此,由于 SSMS 中编写表脚本的代码必须涵盖所有可能发生的情况,因此ALTER TABLE ... CHECK CONSTRAINT ...
即使不需要,它也会输出 a,并且在绝大多数情况下肯定不需要。
1 - 为什么有人希望验证现有行,但不关心新行,这有点神秘,但你明白了。
\n 归档时间: |
|
查看次数: |
2686 次 |
最近记录: |