暂时closures约束(MS SQL)

我正在寻找一种方法来暂时closures所有数据库的约束(如表关系)。

我需要复制(使用插入)一个数据库的表到另一个数据库。 我知道我可以通过以适当的顺序执行命令来达到这个目的(不要中断关系)。

但是,如果我可以暂时closures检查约束并在操作结束后重新打开,那将会更容易。

这可能吗?

只能在SQL 2005+中禁用FK和CHECK约束。 请参阅ALTER TABLE

 ALTER TABLE foo NOCHECK CONSTRAINT ALL 

要么

 ALTER TABLE foo NOCHECK CONSTRAINT CK_foo_column 

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

 -- 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: EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all' -- Re-enable constraints for all tables: EXEC sp_msforeachtable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all' --------------------------------------------------------- 

而且,如果你想validation你没有破坏你的关系,并引入孤儿,一旦你重新武装你的支票,即

 ALTER TABLE foo CHECK CONSTRAINT ALL 

要么

 ALTER TABLE foo CHECK CONSTRAINT FK_something 

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

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

而在这一点上的任何错误将是由于未能满足约束。

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

  • 可以使用TSQL临时禁用外键约束吗?

我目前正在使用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语句将把第一行的数据读入局部variables@foreignKeyName和@tableName。 循环游标时,您可以检查@@ FETCH_STATUS值为0,这表示获取成功。 这意味着循环将继续前进,所以它可以从行集中获取每个连续的外键。 @@ FETCH_STATUS可用于连接上的所有游标。 因此,如果循环使用多个游标,则必须在FETCH语句之后的语句中检查@@ FETCH_STATUS的值。 @@ FETCH_STATUS将反映连接上最新的FETCH操作的状态。 @@ FETCH_STATUS的有效值为:

0 = FETCH成功
-1 = FETCH失败
-2 =被提取的行丢失

在循环内部,代码根据意图是禁用还是启用外键约束(使用CHECK或NOCHECK关键字)来构buildALTER TABLE命令。 然后将语句打印为消息,以便可以观察其进度,然后执行语句。 最后,当所有的行都被迭代后,存储过程closures并释放游标。

请参阅从MSDN杂志禁用约束和触发器