首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WITH CHECK ADD CONSTRAINT后跟CHECK CONSTRAINT与ADD CONSTRAINT

WITH CHECK ADD CONSTRAINT后跟CHECK CONSTRAINT与ADD CONSTRAINT
EN

Stack Overflow用户
提问于 2009-02-09 21:02:12
回答 8查看 133.9K关注 0票数 155

我正在研究SQL Server2008的AdventureWorks示例数据库,我在他们的创建脚本中看到他们倾向于使用以下内容:

代码语言:javascript
复制
ALTER TABLE [Production].[ProductCostHistory] WITH CHECK ADD 
CONSTRAINT [FK_ProductCostHistory_Product_ProductID] FOREIGN KEY([ProductID])
  REFERENCES [Production].[Product] ([ProductID])
GO

紧接着是:

代码语言:javascript
复制
ALTER TABLE [Production].[ProductCostHistory] CHECK CONSTRAINT     
[FK_ProductCostHistory_Product_ProductID]
GO

我在外键(如这里)、唯一约束和常规CHECK约束中看到了这一点;DEFAULT约束使用我更熟悉的常规格式,例如:

代码语言:javascript
复制
ALTER TABLE [Production].[ProductCostHistory] ADD  CONSTRAINT  
[DF_ProductCostHistory_ModifiedDate]  DEFAULT (getdate()) FOR [ModifiedDate]
GO

第一种方法和第二种方法之间有什么区别吗?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2009-02-09 22:21:48

第一个语法是冗余的- WITH CHECK是新约束的默认语法,并且默认情况下约束也是打开的。

此语法是由SQL management studio在生成sql脚本时生成的--我假设它是某种额外的冗余,可能是为了确保即使表的默认约束行为发生更改,也会启用约束。

票数 111
EN

Stack Overflow用户

发布于 2012-09-14 00:54:38

为了演示它是如何工作的--

代码语言:javascript
复制
CREATE TABLE T1 (ID INT NOT NULL, SomeVal CHAR(1));
ALTER TABLE T1 ADD CONSTRAINT [PK_ID] PRIMARY KEY CLUSTERED (ID);

CREATE TABLE T2 (FKID INT, SomeOtherVal CHAR(2));

INSERT T1 (ID, SomeVal) SELECT 1, 'A';
INSERT T1 (ID, SomeVal) SELECT 2, 'B';

INSERT T2 (FKID, SomeOtherVal) SELECT 1, 'A1';
INSERT T2 (FKID, SomeOtherVal) SELECT 1, 'A2';
INSERT T2 (FKID, SomeOtherVal) SELECT 2, 'B1';
INSERT T2 (FKID, SomeOtherVal) SELECT 2, 'B2';
INSERT T2 (FKID, SomeOtherVal) SELECT 3, 'C1';  --orphan
INSERT T2 (FKID, SomeOtherVal) SELECT 3, 'C2';  --orphan

--Add the FK CONSTRAINT will fail because of existing orphaned records
ALTER TABLE T2 ADD CONSTRAINT FK_T2_T1 FOREIGN KEY (FKID) REFERENCES T1 (ID);   --fails

--Same as ADD above, but explicitly states the intent to CHECK the FK values before creating the CONSTRAINT
ALTER TABLE T2 WITH CHECK ADD CONSTRAINT FK_T2_T1 FOREIGN KEY (FKID) REFERENCES T1 (ID);    --fails

--Add the CONSTRAINT without checking existing values
ALTER TABLE T2 WITH NOCHECK ADD CONSTRAINT FK_T2_T1 FOREIGN KEY (FKID) REFERENCES T1 (ID);  --succeeds
ALTER TABLE T2 CHECK CONSTRAINT FK_T2_T1;   --succeeds since the CONSTRAINT is attributed as NOCHECK

--Attempt to enable CONSTRAINT fails due to orphans
ALTER TABLE T2 WITH CHECK CHECK CONSTRAINT FK_T2_T1;    --fails

--Remove orphans
DELETE FROM T2 WHERE FKID NOT IN (SELECT ID FROM T1);

--Enabling the CONSTRAINT succeeds
ALTER TABLE T2 WITH CHECK CHECK CONSTRAINT FK_T2_T1;    --succeeds; orphans removed

--Clean up
DROP TABLE T2;
DROP TABLE T1;
票数 51
EN

Stack Overflow用户

发布于 2013-03-11 08:50:57

在上面关于可信约束的优秀评论的基础上:

代码语言:javascript
复制
select * from sys.foreign_keys where is_not_trusted = 1 ;
select * from sys.check_constraints where is_not_trusted = 1 ;

不受信任的约束,顾名思义,现在不能被信任来准确地表示表中数据的状态。但是,它可以,但可以信任它来检查将来添加和修改的数据。

此外,查询优化器会忽略不受信任的约束。

启用check约束和外键约束的代码相当糟糕,"check“一词有三种含义。

代码语言:javascript
复制
ALTER TABLE [Production].[ProductCostHistory] 
WITH CHECK -- This means "Check the existing data in the table".
CHECK CONSTRAINT -- This means "enable the check or foreign key constraint".
[FK_ProductCostHistory_Product_ProductID] -- The name of the check or foreign key constraint, or "ALL".
票数 25
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/529941

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档