我的触发器不是递归调用

时间:2014-11-11 12:48:54

标签: sql-server tsql recursion database-trigger

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

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

2 个答案:

答案 0 :(得分:2)

嵌套触发器并触发递归:

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

sp_configure "allow nested triggers", 0

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

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

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

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

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

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

答案 1 :(得分:0)

需要注意的一点是,在SQL Server中,每个语句引发一次触发器,每行不引发一次。因此,如果您的update语句更新了多行,则InsertedDeleted伪表将包含多行。您可能希望更改UPDATE语句,如下所示

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