如何编写递归触发器

Gra*_*ell 1 sql-server

我编写了一个更新触发器,它执行可能会调用自身的更新(这是我想要的行为)。

不幸的是,触发器不会调用自身,我不明白为什么。该触发器只是更改任何子记录的值(基于父键),然后我期望在更新该子记录时应再次触发该触发器,并更新该子记录的任何子记录,等等。

我可以手动运行触发器成功完成的相同更新,并且子记录按照我的预期进行设置。

我已经运行 EXEC sp_configure '嵌套触发器' 并且已返回

最小值:0,最大值:1,config_value:1,run_value:1,因此递归似乎已打开。

ALTER TRIGGER [dbo].[DataInstance_Trigger] 
   ON  [dbo].[DataInstance]  
AFTER UPDATE
AS
BEGIN 
  UPDATE DataInstance
  SET
    DataInstance.IsCurrent = i.IsCurrent
    FROM DataInstance di
    Inner join DataContainer dc on
        di.DataContainerId = dc.DataContainerId
    Inner join Inserted i on
        dc.ParentDataContainerId = i.DataContainerId    
    WHERE di.IsCurrent != i.IsCurrent               

END
Run Code Online (Sandbox Code Playgroud)

And*_*mar 5

除了服务器范围的配置之外,您还可以禁用每个数据库的触发器:

ALTER DATABASE databasename SET RECURSIVE_TRIGGERS ON | OFF
Run Code Online (Sandbox Code Playgroud)

或者通过数据库属性 -> 选项 -> 其他 -> 启用递归触发器。

如果检查结果正确,请验证您的第一个触发器是否确实更新了某些内容。我通常使用日志表:

insert into dbo.LogTable (txt) values ('Updated ' + 
    cast(IsNull(@@ROWCOUNT,-1) as varchar(25)) + ' rows.')
Run Code Online (Sandbox Code Playgroud)

为了调试,您还可以使用打印:

print 'Updated ' + cast(IsNull(@@ROWCOUNT,-1) as varchar(25)) + ' rows.'
Run Code Online (Sandbox Code Playgroud)