mysql 触发器 避免递归,防止相互递归执行触发器?

Suppose you have the tables Presentations and Events. When a presentation is saved and contains basic event information, such as location and date, an event will be created automatically using a trigger. (I'm afraid it's impossible for technical reasons to simply keep the data at one place and use a view.) In addition, when changing this information later on in the presentation, the trigger will copy the updates over to the event as well, like so:

CREATE TRIGGER update_presentations

ON Presentations

AFTER UPDATE

AS

BEGIN

UPDATE Events

SET Events.Date = Presentations.Date,

Events.Location = Presentations.Location

FROM Presentations INNER JOIN Events ON Presentations.EventID = Events.ID

WHERE Presentations.ID IN (SELECT ID FROM inserted)

END

Now, the customer wants it so that, if a user ever changes the information in the event, it should go back to the presentation as well. For obvious reasons, I can't do the reverse:

CREATE TRIGGER update_events

ON Events

AFTER UPDATE

AS

BEGIN

UPDATE Presentations

SET Presentations.Date = Events.Date,

Presentations.Location = Events.Location

FROM Events INNER JOIN Presentations ON Events.PresentationID = Presentations.ID

WHERE Events.ID IN (SELECT ID FROM inserted)

END

After all, this would cause each trigger to fire after each other. What I could do is add a column last_edit_by to both tables, containing a user ID. If filled by the trigger with a special invalid ID (say, by making all user IDs of actual persons positive, but user IDs of scripts negative), I could use that as an exit condition:

AND last_edit_by >= 0

This might work, but what I'd like to do is indicate to the SQL server that, within a transaction, a trigger should only fire once. Is there a way to check this? Or perhaps to check that a table has already been affected by a trigger?

Answer thanks to Steve Robbins:

Just wrap the potentially nested UPDATE statements in an IF condition checking for trigger_nestlevel(). For example:

CREATE TRIGGER update_presentations

ON Presentations

AFTER UPDATE

AS

BEGIN

IF trigger_nestlevel() < 2

UPDATE Events

SET Events.Date = Presentations.Date,

Events.Location = Presentations.Location

FROM Presentations INNER JOIN Events ON Presentations.EventID = Events.ID

WHERE Presentations.ID IN (SELECT ID FROM inserted)

END

Note that trigger_nestlevel() appears to be 1-based, not 0-based. If you want each of the two triggers to execute once, but not more often, just check for trigger_nestlevel() < 3 in both triggers.

解决方案

I'm not sure about doing it per transaction, but do you need nested triggers switched on for other parts? If you switch them off on the server then a trigger won't fire from another trigger updating a table.

EDIT (answer from the comments): You will need to alter trigger A to use TRIGGER_NESTLEVEL

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值