如何关闭/打开Microsoft SQL Server中的所有外键和触发器?

时间:2013-11-01 13:37:32

标签: sql sql-server

可能需要插入和修改大量数据。

说实话,在输入问题时我已经知道了答案。但是我找到它是非常困难的,所以我想,这个答案对其他人来说会有所帮助。

但如果你知道更好的方法,你可以自由回答。

所有外键开关

来源:http://www.nxtbook.com/nxtbooks/cmp/msdnmag0407/index.php?startid=27

CREATE PROCEDURE pr_Disable_Foreign_Keys
@disable BIT = 1
AS 
DECLARE
    @sql VARCHAR(500),
    @tableName VARCHAR(128),
    @foreignKeyName VARCHAR(128)

--- A list of all foreign keys and table names
DECLARE foreignKeyCursor CURSOR
FOR SELECT
    ref.constraint_name AS FK_Name,
    fk.table_name AS FK_Table
FROM
    INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS ref
    INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS fk
ON ref.constraint_name = fk.constraint_name
ORDER BY
    fk.table_name,
    ref.constraint_name

OPEN foreignKeyCursor

FETCH NEXT FROM foreignKeyCursor
INTO @foreignKeyName, @tableName

WHILE ( @@FETCH_STATUS = 0 )
    BEGIN
        IF @disable =1
            SET @sql = 'ALTER TABLE ['
                + @tableName + '] NOCHECK CONSTRAINT ['
                + @foreignKeyName + ']'
        ELSE
            SET @sql = 'ALTER TABLE ['
                + @tableName + '] CHECK CONSTRAINT ['
                + @foreignKeyName + ']'
    PRINT 'Executing Statement - ' + @sql

    EXECUTE(@sql)
    FETCH NEXT FROM foreignKeyCursor
    INTO @foreignKeyName, @tableName
END

CLOSE foreignKeyCursor
DEALLOCATE foreignKeyCursor

所有触发开关

来源:http://www.nxtbook.com/nxtbooks/cmp/msdnmag0407/index.php?startid=28

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
        IF @disable = 1 
            SET @sql = 'ALTER TABLE ' + @tableSchema 
                + '.[' + @tableName + '] DISABLE TRIGGER ALL '
        ELSE 
            SET @sql = 'ALTER TABLE ' + @tableSchema 
                + '.[' + @tableName + '] ENABLE TRIGGER ALL' 

        PRINT 'Executing Statement - ' + @sql

        EXECUTE ( @sql )
        FETCH NEXT FROM triggerCursor
        INTO @tableName, @tableSchema
    END

CLOSE triggerCursor
DEALLOCATE triggerCursor

4 个答案:

答案 0 :(得分:10)

禁用所有FK:

EXEC sp_MSforeachtable @command1="ALTER TABLE ? NOCHECK CONSTRAINT ALL"
GO

启用所有FK:

EXEC sp_MSforeachtable @command1="ALTER TABLE ? CHECK CONSTRAINT ALL"
GO

禁用所有触发器:

EXEC sp_MSforeachtable @command1="ALTER TABLE ? DISABLE TRIGGER ALL"
GO

启用所有触发器:

EXEC sp_MSforeachtable @command1="ALTER TABLE ? ENABLE TRIGGER ALL"
GO

当然,请注意,如果您在此之前禁用了任何FK /触发器,则启用脚本将重新启用这些。

答案 1 :(得分:0)

在单个语句中禁用触发器

DISABLE TRIGGERENABLE TRIGGER - 检查MSDN的语法。例如,搜索谷歌:DISABLE TRIGGER t-sql

如,     在所有服务器上禁用触发器; - 禁用在服务器级别和所有登录触发器上定义的所有DML触发器

没有内置方法如何在单个语句中禁用所有FK。

答案 2 :(得分:0)

禁用表格中的所有FK:

ALTER TABLE Table2 NOCHECK CONSTRAINT ALL

禁用表格中的单个FK:

ALTER TABLE Table2 NOCHECK CONSTRAINT FK_Table2_Table1

要启用它们,请将NOCHECK替换为CHECK

答案 3 :(得分:0)

如果要禁用所有FK,然后将它们恢复到原始状态,可以使用以下命令:

禁用所有约束

If OBJECT_ID('tempdb..#tempConstraints') is not null Drop Table #tempConstraints;
GO
IF (SELECT OBJECT_ID('tempdb..#tmpScriptErrors')) IS NOT NULL DROP TABLE #tmpScriptErrors
GO
CREATE TABLE #tmpScriptErrors (Error int)
GO
Create Table #tempConstraints
(
    ConstraintName nVarchar(200),
    TableName nVarchar(200),
    SchemaName nVarchar(200),
    IsNotTrusted bit
);
GO

Begin Tran

Insert into #tempConstraints (ConstraintName, TableName, SchemaName, IsNotTrusted)
Select K.name, object_name(K.parent_object_id), SCHEMA_NAME(T.schema_id), K.Is_Not_Trusted
FROM sys.foreign_keys K 
    Inner Join sys.tables T on K.parent_object_id = T.object_id
Where is_disabled = 0
Union all
Select K.name, object_name(K.parent_object_id), SCHEMA_NAME(T.schema_id), K.Is_Not_Trusted
from sys.check_constraints K
    Inner Join sys.tables T on K.parent_object_id = T.object_id
Where is_disabled = 0


--Disable the Constraints.
Print 'Disabling Constraints'
Exec sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL';

将约束恢复为原始状态

Declare @name nvarchar(200);
Declare @table nvarchar(200);
Declare @schema nvarchar(200);
Declare @script nvarchar(max);
Declare @NotTrusted bit;

Declare constraints_cursor CURSOR FOR 
    Select ConstraintName, TableName, SchemaName, IsNotTrusted
    From #tempConstraints;

Open constraints_cursor;

Fetch Next from constraints_cursor
into @name, @table, @schema, @NotTrusted;

While @@FETCH_STATUS = 0
Begin
    --Restore each of the Constraints back to exactly the state they were in prior to disabling.

    If @NotTrusted = 1
        Set @script = 'ALTER TABLE [' + @schema + '].[' + @table + '] WITH NOCHECK CHECK CONSTRAINT [' + @name + ']';
    Else
        Set @script = 'ALTER TABLE [' + @schema + '].[' + @table + '] WITH CHECK CHECK CONSTRAINT [' + @name + ']';


    exec sp_executesql @script;
    If @@ERROR <> 0
    Begin
        PRINT 'Re-Enabling ' + @name;
        INSERT  INTO #tmpScriptErrors (Error)
        VALUES (1);
    End

    Fetch Next from constraints_cursor
    into @name, @table, @schema, @NotTrusted;
End
Close constraints_cursor;
Deallocate constraints_cursor;

If exists (Select 'x' from #tmpScriptErrors)
    ROLLBACK TRAN;
Else
    COMMIT TRAN;

Drop table #tmpScriptErrors
GO
Drop table #tempConstraints
GO