2

有人可以仔细检查我的精简示例吗?当 Documents 表更新时,我希望它更新 Queue 表上的 EntryDate。但是,我不希望 Queue 表上的触发器仅针对此过程触发。意思是,如果其他进程在该进程运行时更新 Queue 表上的 EntryDate,我希望 Queue 表上的触发器为该特定事务触发。我不确定是否需要对以下代码进行任何类型的锁定,以确保没有其他进程被踩到。谢谢!

create trigger [dbo].[Documents_trigUpdate] on [dbo].[Documents]
for update
as

begin transaction

alter table [Queue] disable trigger Queue_trigUpdate
update  [Queue] set EntryDate = getdate()
alter table [Queue] enable trigger Queue_trigUpdate

commit transaction

go
4

3 回答 3

11

您需要避免禁用然后重新启用触发器,因为这将影响所有进程,而不仅仅是当前进程。如果您放置某种类型的锁,您将序列化您的代码,这可能会成为您系统的瓶颈。

另一种方法是使用Context_info当前连接的 ,Queue如果已设置特定上下文,则将触发器更改为不执行。

本文介绍了这种技术,下面提供了一个示例:

-- Creating the queue trigger
create trigger [dbo].[Queue_trigUpdate] on [dbo].[Queue]
for update
as   

declare @Cinfo varbinary(128)  
select @Cinfo = Context_Info()  
if @Cinfo = 0x55555  
    return  

print 'Trigger Executed'  
-- Actual code goes here  
go

要防止触发器被执行,您可以执行以下操作:

create trigger [dbo].[Documents_trigUpdate] on [dbo].[Documents]
for update
as

-- Save the original context info    
declare @originalContextInfo VARBINARY(128)
set @originalContextInfo = Context_Info()

set Context_Info 0x55555 
update  [Queue] set EntryDate = getdate()

-- Reset the context info
set Context_Info @originalContextInfo 
go
于 2012-08-01T19:53:37.580 回答
0

我以前做过这个,我不知道这是否是最好的方法,甚至不知道你想要什么,但你可以使用 CONTEXT_INFO()。

在要忽略的进程中,运行:

DECLARE @ContextInfo varbinary(128)
SET @ContextInfo = CAST('SomethingMeaningfulToYou' AS varbinary(128))
SET Context_Info @ContextInfo 

然后,在您的触发器中,如果说,更新行。

CREATE TRIGGER X 
ON TABLE Y 
AFTER UPDATE AS
BEGIN
    UPDATE Something
    SET something = somethingelse
    WHERE yourconditions AND 
         (CONTEXT_INFO IS NULL OR CONTEXT_INFO() <> CAST('SomethingMeaningfulToYou' AS varbinary(128)))
END
于 2012-08-01T19:53:33.933 回答
-2

您应该能够调用DISABLE TRIGGER执行一些工作,然后在完成后调用ENABLE TRIGGER

于 2012-08-01T19:52:11.797 回答