暂时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杂志禁用约束和触发器
- Xcode 5.1 – 无需编译的架构(ONLY_ACTIVE_ARCH = YES,活动arch = x86_64,VALID_ARCHS = i386)
- 查询列出数据库中每个表中的logging数