关于sql server:暂时关闭约束(MS SQL)

Turn off constraints temporarily (MS SQL)

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

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

但是,如果我可以暂时关闭检查约束,并在操作完成后重新打开它,这会更容易。

这有可能吗?


您只能在SQL 2005+中禁用fk和check constraints。参阅更改表

1
ALTER TABLE foo NOCHECK CONSTRAINT ALL

1
ALTER TABLE foo NOCHECK CONSTRAINT CK_foo_column

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


1
2
3
4
5
6
7
8
9
10
11
12
13
-- 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'
---------------------------------------------------------


而且,如果你想证实你没有破坏你的关系和介绍孤儿,一旦你重新武装了你的支票,也就是说。

1
ALTER TABLE foo CHECK CONSTRAINT ALL

1
ALTER TABLE foo CHECK CONSTRAINT FK_something

然后,您可以重新运行并对任何选中的列进行更新,如下所示:

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

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


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

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

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


禁用和启用所有外键

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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杂志禁用约束和触发器