在调用其他代码之前,T-SQL触发器会发生更改

时间:2009-08-26 22:26:34

标签: sql sql-server tsql triggers

我有一张桌子,我们的电话是 [MYTABLE] ,带有 FOR INSERT,UPDATE 触发器。

触发器需要执行存储过程,该过程将根据对 [MYTABLE] 所做的更改执行一些操作。我无法将存储过程的代码移动到触发器中。

到目前为止,非常好......因为在进行更改后触发器执行,存储过程无需访问 [inserted] [已删除] metatables。

但是......触发器需要更改一个附加字段 [LastModified] smalldatetime),以便存储过程可以在其处理中使用该数据。这是,因此存储过程可以看到插入/更新的内容...该过程可能会根据触发它的更新中未包含的其他记录执行许多操作。

问题是,如果我的触发器改变 [LastModified] ,那么什么都不(如果我关闭了递归触发器),或者它会结束调用存储过程两次 - 一次是因为原始触发更改,再次因为我更改为 [LastModified]

我如何解决这个问题(a) [LastModified] 随每次更改而更新;(b)存储过程仅在 有权访问后调用 [LastModified] 的新值?

我有两个想法,但他们闻起来很有趣,所以我宁愿看看是否有更直接的解决方案。

修改

好的,这是我到目前为止的解决方案,也许这将有助于讨论:

1。使用两个触发器。一个是“INSTEAD OF”触发器,它将处理用户对记录的更新并将更改LastModified,但如果更新来自来自 SP,则会快速返回(它可以根据修改的列来判断。另一个是“AFTER”触发器,它会调用EXEC。此触发器通过INSTEAD OF触发器获取LastModified列已应用的更新。至少我希望它是如何运作的。

2。将ModifiedDate移动到另一个表。这样,我可以有一个AFTER INSERT / UPDATE触发器,如果用户启动INSERT / UPDATE,则将审计记录添加到另一个表并拨打SP。然后SP会修改其他记录,这会导致触发器再次触发,但它会很快识别出情况并返回RETURN而不需要做更多的工作。

第一个解决方案的缺点是我必须在触发器中维护列列表,因此INSTEAD OF更新实际上完成了预期的工作(因为我在列表中添加了一列,ModifiedDate,我不能只是INSERT INTO tbl FROM inserted,我必须指定列。)

2 个答案:

答案 0 :(得分:3)

您是否尝试过IF UPDATE(LastModified)指令?

CREATE TRIGGER XYZ ON MYTABLE 
FOR INSERT, UPDATE 
AS 
BEGIN 
IF UPDATE(LastModified) 
  RETURN 
ELSE 
  BEGIN
    UPDATE MYTABLE SET LastModified = GETDATE() 
    FROM MYTABLE INNER JOIN INSERTED ON MYTABLE.ID = INSERTED.ID
    EXEC TheStoreProc
  END
END;

答案 1 :(得分:0)

我不确定我理解你所描述的流程。是吗:

  1. 记录已更新
  2. 更新触发器proc称为
  3. 触发更新LastModified字段
  4. 触发器调用另一个proc
  5. 只要“另一个proc”不更新同一个表,它应该可以正常工作, 这将再次启动触发器。

    如果“另一个proc” 再次更新表,您可以移动这些更新 在调用“另一个proc”之前进入触发器。

    这有什么帮助吗?