我有一张桌子,我们的电话是 [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,我必须指定列。)
答案 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)
我不确定我理解你所描述的流程。是吗:
只要“另一个proc”不更新同一个表,它应该可以正常工作, 这将再次启动触发器。
如果“另一个proc” 再次更新表,您可以移动这些更新 在调用“另一个proc”之前进入触发器。
这有什么帮助吗?