暂时关闭约束(MS SQL)

我正在寻找一种方法暂时关闭所有DB的约束(如表关系)。

我需要复制(使用insert)一个DB的表到另一个DB。 我知道我可以通过以适当的顺序执行命令(不破坏关系)来实现这一点

但是,如果我可以暂时关闭检查约束,并在操作结束后重新启用它,那就更容易了。

这可能吗?

362858 次浏览

你可以禁用FK和CHECK约束只有在SQL 2005+。看到ALTER TABLE

ALTER TABLE foo NOCHECK CONSTRAINT ALL

ALTER TABLE foo NOCHECK CONSTRAINT CK_foo_column

主键和唯一约束不能被禁用,但如果我正确理解你的话,这应该是可以的。

而且,如果你想验证你没有破坏你的关系和介绍孤儿,一旦你重新武装你的支票,即。

ALTER TABLE foo CHECK CONSTRAINT ALL

ALTER TABLE foo CHECK CONSTRAINT FK_something

然后你可以运行回来,对任何选中的列进行更新,如下所示:

UPDATE myUpdatedTable SET someCol = someCol, fkCol = fkCol, etc = etc

在这一点上的任何错误都是由于没有满足约束条件。

实际上,您可以在单个SQL命令中禁用所有数据库约束,并调用另一个命令重新启用它们。看到的:

我目前正在使用SQL Server 2005,但我几乎可以肯定这种方法也适用于SQL 2000

禁用和启用所有外键

CREATE PROCEDURE pr_Disable_Triggers_v2
@disable BIT = 1
AS
DECLARE @sql VARCHAR(500)
,   @tableName VARCHAR(128)
,   @tableSchema VARCHAR(128)


-- List of all tables
DECLARE triggerCursor CURSOR FOR
SELECT  t.TABLE_NAME AS TableName
,   t.TABLE_SCHEMA AS TableSchema
FROM    INFORMATION_SCHEMA.TABLES t
ORDER BY t.TABLE_NAME, t.TABLE_SCHEMA


OPEN    triggerCursor
FETCH NEXT FROM triggerCursor INTO @tableName, @tableSchema
WHILE ( @@FETCH_STATUS = 0 )
BEGIN


SET @sql = 'ALTER TABLE ' + @tableSchema + '.[' + @tableName + '] '
IF @disable = 1
SET @sql = @sql + ' DISABLE TRIGGER ALL'
ELSE
SET @sql = @sql + ' ENABLE TRIGGER ALL'


PRINT 'Executing Statement - ' + @sql
EXECUTE ( @sql )


FETCH NEXT FROM triggerCursor INTO @tableName, @tableSchema


END


CLOSE triggerCursor
DEALLOCATE triggerCursor
首先,foreignKeyCursor游标被声明为SELECT语句 它收集外键列表及其表名。接下来, 打开游标并执行初始FETCH语句。这 FETCH语句将第一行的数据读入本地 变量@foreignKeyName和@tableName。当循环遍历 光标,您可以检查@@FETCH_STATUS的值为0,这 表示读取成功。这意味着循环将会 继续向前移动,以便它可以获得每个连续的外键 从行集中。的所有游标都可以使用 连接。如果你循环多个游标,它就是 检查语句中@@FETCH_STATUS的值很重要 紧接着FETCH语句。@@FETCH_STATUS将被反射 连接上最近一次FETCH操作的状态。 @@FETCH_STATUS的有效值为:

0 = FETCH was successful
-1 = FETCH was successful
-2 =未获取的行

在循环中,代码以不同的方式构建ALTER TABLE命令 取决于意图是禁用还是启用外部 关键字约束(使用CHECK或NOCHECK关键字)。这个陈述是 然后将其打印为消息,以便观察其进展,然后 语句执行。最后,当所有行都迭代完成时

.通过,存储过程关闭并释放游标

看到禁用MSDN杂志中的约束和触发器

-- Disable the constraints on a table called tableName:
ALTER TABLE tableName NOCHECK CONSTRAINT ALL


-- Re-enable the constraints on a table called tableName:
ALTER TABLE tableName WITH CHECK CHECK CONSTRAINT ALL
---------------------------------------------------------


-- Disable constraints for all tables in the database:
EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'


-- Re-enable constraints for all tables in the database:
EXEC sp_msforeachtable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT ALL'
---------------------------------------------------------