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