【问题标题】:My trigger is not calling recursively我的触发器没有递归调用
【发布时间】:2015-01-08 00:39:10
【问题描述】:

下面是我的触发器,不是递归调用的,请解释一下

USE [TESTING]
GO
/****** Object:  Trigger [dbo].[UPDATETRIGGER] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[UPDATETRIGGER] on [dbo].[TEST]
 FOR UPDATE 
 AS
  UPDATE dbo.TEST
    SET lastEditedDate=GetDate()
    FROM INSERTED newdata
    WHERE TEST.MasterK = newdata.MasterK

【问题讨论】:

  • 递归是什么意思?
  • 调用触发器本身。因为里面更新的表是有触发器的。
  • 需要不递归调用它的原因,因为在更新 TEST 表时调用此触发器,现在此触发器正在更新 TEST 表.. 所以它再次更新表,然后如此由于表已更新,因此调用了触发器 .. 现在它应该是循环的,但这没有发生,我需要它没有发生的原因。下面是我们在 ms sql 上执行 sp_configure 时递归和嵌套触发器的值。这里我们没有关闭该属性,所以为什么它没有发生
  • 服务器触发器递归 0 1 1 1 嵌套触发器 0 1 1 1

标签: sql-server tsql recursion database-trigger


【解决方案1】:

嵌套触发器和触发器递归:

默认情况下,Adaptive Server 允许嵌套触发器。要防止触发器嵌套,请使用 sp_configure 将允许嵌套触发器选项设置为 0(关闭):

sp_configure "allow nested triggers", 0

触发器可以嵌套到 16 级深度。如果触发器更改了另一个触发器所在的表,则第二个触发器将触发,然后可以调用第三个触发器,依此类推。如果链中的任何触发器引发无限循环,则超出嵌套级别并且触发器中止,回滚包含触发器查询的事务。

注意:由于触发器被放入事务中,因此嵌套触发器集的任何级别的失败都会取消整个事务:所有数据修改都会回滚。为您的触发器提供消息和其他错误处理和调试帮助,以确定故障发生的位置。

全局变量@@nestlevel 包含当前执行的嵌套级别。每次存储过程或触发器调用另一个存储过程或触发器时,嵌套级别都会递增。创建缓存语句时,嵌套级别也会加一。如果超过最大值 16,则事务中止。

如果触发器调用的存储过程执行的操作会导致触发器再次触发,则仅在启用嵌套触发器时才会重新激活触发器。除非触发器中有限制递归次数的条件,否则这会导致嵌套级溢出。

例如,如果更新触发器调用执行更新的存储过程,则如果禁用允许嵌套触发器,则触发器和存储过程执行一次。如果启用了允许嵌套触发器,并且更新次数不受触发器或过程中的条件限制,则过程或触发器循环将继续,直到超过 16 级最大嵌套值。

默认情况下,触发器不会调用自身以响应触发器内对同一表的第二次数据修改,无论允许嵌套触发器配置参数的设置如何。设置选项 self_recursion 使触发器能够作为触发器内的数据修改的结果再次触发。例如,如果表的一列上的更新触发器导致对另一列的更新,则更新触发器在 self_recursion 禁用时仅触发一次,但如果 self_recursion 设置为 on,它最多可以触发 16 次。为了进行自递归,还必须启用允许嵌套触发器配置参数。

【讨论】:

  • 最大@@nestlevel 在 sql-server 中为 32
【解决方案2】:

需要注意的一点是,在 SQL Server 中,每个语句触发一次,而不是每行触发一次。因此,如果您的更新语句更新多行,那么InsertedDeleted 伪表将包含多行。您可能想要更改您的 UPDATE 声明,如下所示

  UPDATE t
    SET lastEditedDate = GetDate()
    FROM dbo.TEST t
    JOIN INSERTED i ON t.MasterK = i.MasterK

【讨论】:

  • 不,我的触发器没有被递归调用,不知道为什么,我需要它没有被递归调用的原因。
猜你喜欢
  • 2011-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-17
  • 1970-01-01
  • 2016-03-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多