我正在研究SQL Server2008的AdventureWorks示例数据库,我在他们的创建脚本中看到他们倾向于使用以下内容:
ALTER TABLE [Production].[ProductCostHistory] WITH CHECK ADD
CONSTRAINT [FK_ProductCostHistory_Product_ProductID] FOREIGN KEY([ProductID])
REFERENCES [Production].[Product] ([ProductID])
GO紧接着是:
ALTER TABLE [Production].[ProductCostHistory] CHECK CONSTRAINT
[FK_ProductCostHistory_Product_ProductID]
GO我在外键(如这里)、唯一约束和常规CHECK约束中看到了这一点;DEFAULT约束使用我更熟悉的常规格式,例如:
ALTER TABLE [Production].[ProductCostHistory] ADD CONSTRAINT
[DF_ProductCostHistory_ModifiedDate] DEFAULT (getdate()) FOR [ModifiedDate]
GO第一种方法和第二种方法之间有什么区别吗?
发布于 2009-02-09 22:21:48
第一个语法是冗余的- WITH CHECK是新约束的默认语法,并且默认情况下约束也是打开的。
此语法是由SQL management studio在生成sql脚本时生成的--我假设它是某种额外的冗余,可能是为了确保即使表的默认约束行为发生更改,也会启用约束。
发布于 2012-09-14 00:54:38
为了演示它是如何工作的--
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;发布于 2013-03-11 08:50:57
在上面关于可信约束的优秀评论的基础上:
select * from sys.foreign_keys where is_not_trusted = 1 ;
select * from sys.check_constraints where is_not_trusted = 1 ;不受信任的约束,顾名思义,现在不能被信任来准确地表示表中数据的状态。但是,它可以,但可以信任它来检查将来添加和修改的数据。
此外,查询优化器会忽略不受信任的约束。
启用check约束和外键约束的代码相当糟糕,"check“一词有三种含义。
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".https://stackoverflow.com/questions/529941
复制相似问题