当前位置: 首页 > 面试题库 >

防止相互递归执行触发器?

公孙黎昕
2023-03-14
问题内容

假设您有表格PresentationsEvents。保存演示文稿并包含基本事件信息(如位置和日期)后,将使用触发器自动创建事件。(由于技术原因,恐怕不可能仅将数据保存在一个位置并使用视图。)此外,在稍后的演示中更改此信息时,触发器也会将更新复制到事件中,像这样:

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

现在,客户需要它,这样,如果用户更改了 事件中 的信息,它也应该返回到演示。出于明显的原因,我不能相反:

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

毕竟,这将导致每个触发器彼此触发。我可以做的是last_edit_by在两个表中添加一列,其中包含一个用户ID。如果触发器用特殊的无效ID填充(例如,通过使实际人员的所有用户ID为正,而使脚本的用户ID为负),则可以将其用作退出条件:

    AND last_edit_by >= 0

这可能有效,但是我想做的是向SQL Server指示,在事务中,触发器应该只触发一次。有办法检查吗?还是要检查表是否已被触发器影响?

感谢史蒂夫罗宾斯:

只需将可能嵌套的UPDATE语句包装在IF条件中检查即可trigger_nestlevel()。例如:

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

请注意,这trigger_nestlevel()似乎是从1开始的,而不是从0开始的。如果您希望两个触发器中的每个触发器执行一次,但不更频繁地执行,则只需检查trigger_nestlevel() < 3两个触发器。


问题答案:

我不确定是否要在每个事务中执行此操作,但是是否需要为其他部分打开嵌套触发器?如果您在服务器上关闭它们,则不会从另一个更新表的触发器中触发一个触发器。

编辑(评论的答案): 您将需要更改触发器A才能使用 TRIGGER_NESTLEVEL



 类似资料:
  • 假设我编写这样的代码: 我如何让Kotlin优化这些相互递归的函数,以便在不抛出StackOverflower错误的情况下运行main?tailrec关键字适用于单函数递归,但没有更复杂的功能。我还看到一个警告,在使用关键字tailrec的地方没有找到尾部调用。也许这对编译器来说太难了?

  • 在我的progress函数中,它将到达递归的底部,但是我期望返回的值没有改变。 这应该返回true,它符合条件(记录文本),但随后继续移动,并且始终返回false。

  • 问题内容: 这是一个程序,它使用递归和执行程序来读取以前格式的信息站点。它工作正常,我的问题是测试程序是否完成和成功通知。 如果 levels.length = 1 ,则规则执行器运行良好,但是如果 levels.length > 1将出现错误:线程“ pool-1-thread-138”中的异常java.util.concurrent.RejectedExecutionException 问题答

  • 问题内容: 如果我有标记: .a类具有与之关联的悬停类 .b类具有与之关联的伪元素…像这样: CSS是否有可能防止伪元素触发.a类悬停? 小提琴 问题答案: 以下CSS为现代浏览器(而非IE10-)提供了诀窍: 允许元素不接收悬停/点击事件。 警告 对非SVG元素的支持处于相对早期的状态。developer.mozilla.org给您以下警告: 在CSS中将指针事件用于非SVG元素是实验性的。 该

  • 问题内容: 我有一个ajax电话 现在,这里是10分钟后收到的答复。因此,ajax调用被多次调用。为什么会发生这种情况/我们如何确保ajax调用仅被调用一次? 问题答案: 禁用按钮的另一种方法是使用.one()方法,并在回调后重新绑定事件处理程序:

  • 是否存在防止DynamoDB流在每次DynamoDB更改时触发λ的方法? 这些数字并不准确,但是假设step函数将连续运行10次,那么它将更新DynamoDB 3次。在step函数触发lambda之前,这是调用lambda的30倍。有什么方法可以阻止这些lambda调用吗?