2014-09-25 238 views
0

我是触发器的新手,我处于必须使用触发器的位置。我有一个在桌面上有两个触发器的天青数据库,一个在插入,一个在更新。在触发另一个触发器后启用触发器

插入:当记录插入表格时触发。复制一个列到另一个:

CREATE TRIGGER [dbo].[tr_Set_Adjusted_StartDateTime] 
ON [dbo].[Work] 
AFTER INSERT 
AS 
BEGIN 
    UPDATE dbo.Work 
    SET [ActualStartDateTime] = [work].[StartDateTime] 
    FROM inserted 
    WHERE dbo.Work.WorkUID = inserted.WorkUID; 
END 

更新触发(火灾时,该记录被更新):

CREATE TRIGGER [dbo].[tr_Set_Actual_EndDateTime] 
ON [dbo].[Work] 
AFTER UPDATE 
AS 
    IF((Select [ActualEndDateTime] from Deleted) is null) 
    BEGIN 
     UPDATE dbo.Work 
     SET [ActualEndDateTime] = GETUTCDATE() 
     FROM deleted 
     WHERE dbo.Work.WorkUID = deleted.WorkUID; 
    END 

第二个触发应该只执行一次:第一次记录更新。因为插入记录的存储过程不会填充所有列。

第二个触发器原本没有IF语句。但有一个管理站点可以操纵数据库并启动更新触发器。

IF语句现在会立即自动触发更新触发器。

有没有办法禁用更新触发器,如果​​它被另一个触发器执行?或者只在记录创建后启用更新触发器?

+0

注意--''''''''''''可以包含*多行*(或无行)。所以'IF'检查可能会被破坏,因为您可能处于* some行的测试结果为真的情况,对于其他行,测试将是错误的。 – 2014-09-26 06:44:46

回答

0

如果在表上有一个After Update触发器,每当该表上有更新时,它都会触发。你不能告诉触发器只发射一次。

但是有一种解决方法。您可以在该表中添加一个字段BIT字段,并将其值设置为1。永远不要直接操纵该字段。而你的UPDATE触发器

UPDATE w 
SET [ActualEndDateTime] = GETUTCDATE() 
    ,[Tr_Update] = 1 
FROM deleted d INNER JOIN dbo.Work w ON w.WorkUID = d.WorkUID 
WHERE [Tr_Update] = 0 
AND [ActualEndDateTime] IS NULL 

在一个侧面内注意要检查,如果用户还没有把你想当前日期时间添加到[ActualEndDateTime]列的任何日期。而且由于这是一个经过更新的触发,如果你只是执行与WHERE子句[ActualEndDateTime] IS NULL上面的语句,

这将更新[ActualEndDateTime]到当前日期时间一行时,首次和下一次因为[ActualEndDateTime]场更新不会是空的,反而会将其过滤出来。

UPDATE w 
SET [ActualEndDateTime] = GETUTCDATE() 
FROM deleted d INNER JOIN dbo.Work w ON w.WorkUID = d.WorkUID 
WHERE [ActualEndDateTime] IS NULL 
+0

对不起,我现在比较困惑。你是否在插入触发器中将新位字段设置为1?我不跟随你的答案如何工作。操作流程如下:插入 - >触发器1(更新) - >触发器2(更新)。我需要它:插入 - >触发器1(更新)。然后稍后当记录更新(而不是来自插入触发器)触发器2.将RECURSIVE_TRIGGERS {OFF}设置在这里工作吗? – Ju66ernaut 2014-09-26 04:59:24