我正在寻找一种方法暂时关闭所有DB的约束(如表关系)。
我需要复制(使用insert)一个DB的表到另一个DB。 我知道我可以通过正确地执行命令来实现这一点(不破坏关系)。
但是,如果我可以暂时关闭检查约束,并在操作结束后重新启用它,那就更容易了。
这可能吗?
我正在寻找一种方法暂时关闭所有DB的约束(如表关系)。
我需要复制(使用insert)一个DB的表到另一个DB。 我知道我可以通过正确地执行命令来实现这一点(不破坏关系)。
但是,如果我可以暂时关闭检查约束,并在操作结束后重新启用它,那就更容易了。
这可能吗?
当前回答
只能在SQL 2005+中禁用FK和CHECK约束。参见ALTER TABLE
ALTER TABLE foo NOCHECK CONSTRAINT ALL
or
ALTER TABLE foo NOCHECK CONSTRAINT CK_foo_column
主键和唯一约束不能被禁用,但如果我正确理解你的话,这应该是可以的。
其他回答
禁用和启用所有外键
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
First, the foreignKeyCursor cursor is declared as the SELECT statement that gathers the list of foreign keys and their table names. Next, the cursor is opened and the initial FETCH statement is executed. This FETCH statement will read the first row's data into the local variables @foreignKeyName and @tableName. When looping through a cursor, you can check the @@FETCH_STATUS for a value of 0, which indicates that the fetch was successful. This means the loop will continue to move forward so it can get each successive foreign key from the rowset. @@FETCH_STATUS is available to all cursors on the connection. So if you are looping through multiple cursors, it is important to check the value of @@FETCH_STATUS in the statement immediately following the FETCH statement. @@FETCH_STATUS will reflect the status for the most recent FETCH operation on the connection. Valid values for @@FETCH_STATUS are: 0 = FETCH was successful -1 = FETCH was unsuccessful -2 = the row that was fetched is missing Inside the loop, the code builds the ALTER TABLE command differently depending on whether the intention is to disable or enable the foreign key constraint (using the CHECK or NOCHECK keyword). The statement is then printed as a message so its progress can be observed and then the statement is executed. Finally, when all rows have been iterated through, the stored procedure closes and deallocates the cursor.
请参阅MSDN杂志中的禁用约束和触发器
只能在SQL 2005+中禁用FK和CHECK约束。参见ALTER TABLE
ALTER TABLE foo NOCHECK CONSTRAINT ALL
or
ALTER TABLE foo NOCHECK CONSTRAINT CK_foo_column
主键和唯一约束不能被禁用,但如果我正确理解你的话,这应该是可以的。
而且,如果你想验证你没有破坏你的关系和介绍孤儿,一旦你重新武装你的支票,即。
ALTER TABLE foo CHECK CONSTRAINT ALL
or
ALTER TABLE foo CHECK CONSTRAINT FK_something
然后你可以运行回来,对任何选中的列进行更新,如下所示:
UPDATE myUpdatedTable SET someCol = someCol, fkCol = fkCol, etc = etc
在这一点上的任何错误都是由于没有满足约束条件。
-- 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'
---------------------------------------------------------
实际上,您可以在单个SQL命令中禁用所有数据库约束,并调用另一个命令重新启用它们。看到的:
使用TSQL可以暂时禁用外键约束吗?
我目前正在使用SQL Server 2005,但我几乎可以肯定这种方法也适用于SQL 2000