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

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

但如果我可以暂时关闭检查约束并在操作完成后将其重新打开,那就更容易了。

这可能吗?

有帮助吗?

解决方案

您可以禁用FK和CHECK约束<击>仅在SQL 2005 + 。请参阅 ALTER TABLE

ALTER TABLE foo NOCHECK CONSTRAINT ALL

ALTER TABLE foo NOCHECK CONSTRAINT CK_foo_column

主键和唯一约束不能被禁止的,但如果我理解正确的话,你这个应该没问题。

其他提示

-- 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'
---------------------------------------------------------

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

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语句将读取第一行的数据到本地   变量@foreignKeyName和@tablename。当通过循环   光标,您可以通过检查@@ FETCH_STATUS为0值,这   指示获取成功。这意味着循环将   继续往前走,因此可以得到每个连续的外键   从行集。 @@ FETCH_STATUS可对所有游标   连接。所以,如果你是通过多个游标循环,这是   重要的是检查在声明FETCH_STATUS的@@值   紧随其后的FETCH语句。 @@ FETCH_STATUS反映   对于最近的读取状态的连接操作。   对于@@ FETCH_STATUS有效值是:

     

0 = FETCH成功结果   -1 = FETCH是不成功的结果   -2 =,这是取出的行缺少

     

在循环内部,代码建立ALTER TABLE命令不同   根据意向是否禁用或启用外国   键约束(使用CHECK或NOCHECK关键字)。该声明是   然后打印为消息,以便它的进展,可以观察,然后将   语句执行。最后,当所有行的迭代   通过,所存储的过程关闭并释放光标。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top