2014-01-24 42 views
0

我处于这种情况,我必须禁用所有触发器并启用它们才能加速备份的特定工作。 我用下面的禁用代码我所有触发器启用细节触发器,Sql服务器

EXEC sp_msforeachtable "ALTER TABLE ? DISABLE TRIGGER ALL" 
GO 

我一直在一个表#InitiallyDesabledTR(object_ID, Name)与OBJECT_ID和我所有的触发器开始禁用的名称。

Create Table #InitiallyDesabledTR(Object_id int, name varchar (45)) 
Insert into #InitiallyDesabledTR(Object_id, name) 
(
    SELECT object_id, name 
    FROM sys.triggers tr 
    WHERE tr.is_disabled = 1 

    ) 

难道任何一个对我怎么能重新启用我所有在场的触发器在我的数据库除了那些存在于我的临时表#InitiallyDesabledTR的想法。

+1

感谢您的回复:) – Sammoud

回答

0

这将禁用所有尚未禁用的表触发器,然后仅重新启用禁用的表触发器。在SQL Server 2008 R2中测试过。我改用物理表dbAdmin_TriggersToReEnable来跟踪作为工作一部分而被禁用的触发器,而不是使用临时表来跟踪最初禁用的触发器。这可以确保,如果作业由于某种原因在触发器被禁用之后失败,但是在它们被重新启用之前,那么您仍然有一个仍然需要重新启用的触发器的列表,并且这些触发器将在下一次运行。使用原始设置,如果禁用了所有触发器,并且在备份作业处理期间出现错误,则所有触发器都将保持禁用状态,并且您将失去对最初禁用的触发器的引用,因为临时表, #InitiallyDesabledTR,会消失。

设置:创建一个表dbo.dbAdmin_TriggersToReEnable和2存储过程dbo.spDbAdmin_DisableAllTableTriggersdbo.spDbAdmin_ReEnableTriggers

if not exists(select 1 from sys.tables t where t.name = 'dbAdmin_TriggersToReEnable') 
    create table dbo.dbAdmin_TriggersToReEnable(
     object_id int not null, 
     parent_id int not null, 
     triggerName sysname not null, 
     tableSchemaName sysname not null, 
     tableName sysname not null, 
     creationdate datetime 
     , constraint PK_dbAdmin_TriggersToReEnable PRIMARY KEY CLUSTERED (object_id) 
    ); 
go 

CREATE PROC dbo.spDbAdmin_DisableAllTableTriggers 
AS 
BEGIN 
    set nocount on; 

    INSERT INTO dbo.dbAdmin_TriggersToReEnable(object_id, parent_id, triggerName, tableSchemaName, tableName, creationdate) 
    SELECT tr.object_id, tr.parent_id, tr.name AS triggerName, schema_name(tbl.schema_id) as tableSchemaName, tbl.name as tableName, getdate() as creationdate 
    FROM sys.triggers tr 
     INNER JOIN sys.tables tbl on tbl.object_id = tr.parent_id 
     LEFT JOIN dbo.dbAdmin_TriggersToReEnable e on tr.object_id = e.object_id 
    WHERE tr.is_disabled = 0 
     AND e.object_id is null --not already in the table 
    ; 

    --disable all triggers 
    EXEC sp_msforeachtable 'ALTER TABLE ? DISABLE TRIGGER ALL' 

END 
GO 

CREATE PROC dbo.spDbAdmin_ReEnableTriggers 
AS 
BEGIN 
    declare @object_id int, @schemaName nvarchar(256), @tableName nvarchar(256), @triggerName nvarchar(3000), @sql nvarchar(max); 

    select @object_id = min(e.object_id) from dbo.dbAdmin_TriggersToReEnable e; 

    while exists(select 1 from dbo.dbAdmin_TriggersToReEnable) 
    begin 
     select @schemaName = t.tableSchemaName, @tableName = t.tableName, @triggerName = t.triggerName 
     from dbo.dbAdmin_TriggersToReEnable t 
     where t.object_id = @object_id 
     ; 

     set @sql = 'ALTER TABLE ' + QUOTENAME(@schemaName) + '.' + QUOTENAME(@tableName) + ' ENABLE TRIGGER ' + QUOTENAME(@triggerName) ; 

     EXEC(@sql); 

     delete t from dbo.dbAdmin_TriggersToReEnable t where t.object_id = @object_id; 
     select @object_id = min(t.object_id) from dbo.dbAdmin_TriggersToReEnable t; 
    end; 

END 
GO 

然后你可以设置一个SQL代理作业使用以下步骤:

--Step 1 
EXEC dbo.spDbAdmin_DisableAllTableTriggers; 

--Step 2 
--....do your backup job work here... 

--Step 3 
EXEC dbo.spDbAdmin_ReEnableTriggers; 
+0

这正是我需要的。 我必须更新代码才能使所有数据库中的启用和禁用触发器成为可能。事实上,我必须适应所有的触发器,非clustred索引和约束条件,以便在短暂的延迟时间内对可能的数据进行近100G的特定备份。 – Sammoud

+0

只是好奇,为什么是为了备份的目的禁用触发器?我很惊讶这会影响备份时间。如果在备份作业正在运行时进行任何数据修改,则没有任何触发器可以运行,这可能会导致数据问题。 – BateTech

+0

@ Sammoud,如果这回答了你的问题,你能标记为答案吗? – BateTech

0

我必须禁用我的所有索引,触发器和限制都可以加速我的备份。 即使采取这种行动,通过执行接近900行的代码,此备份时间也会超过15个小时。 我没有可能使级联下降,这就是为什么我必须检查初始表和所有实例之间的所有完整性。 ps。我的唯一标准就是创建订单的日期。

+0

因此,这不是SQL Server备份(http://technet.microsoft.com/en-us/library/ms187510.aspx),而是通过插入(并删除它)来执行数据“备份”的作业听起来像参考约束是一个问题)基于订单创建日期的数据? – BateTech

+0

基于数据的备份(删除2013年之前创建的所有订单) 我有超过120G的数据和超过450个数据库在我的数据库中+ 477次查看... 想象一下我必须做的工作... 但好消息是脚本已经完成,第一次测试看起来不错 – Sammoud