为何该AFTER UPDATE触发器未触发递归执行?
问题解析:AFTER UPDATE触发器未递归触发的原因
你的触发器没递归触发主要有两个核心原因:
1. SQL Server默认禁用递归触发器
SQL Server数据库的RECURSIVE_TRIGGERS选项默认是OFF状态,这个设置直接阻止了触发器因自身内部的更新操作而递归触发。除非你手动执行语句开启这个选项:
ALTER DATABASE YourDatabaseName SET RECURSIVE_TRIGGERS ON;
但就算开启了这个选项,还有第二个因素会阻止递归触发。
2. 触发器内的UPDATE操作可能未实际修改数据
你的触发器逻辑里,两种分支的UPDATE都可能不会真正改变字段值:
- 当价格涨幅≤15%时,你把
ListPrice设为@NewListPrice,而这个值就是当前表中已经被更新后的新值(因为AFTER触发器是在原UPDATE执行完成后触发的),所以这个UPDATE相当于把字段值设成和当前值一样,SQL Server会跳过这个无意义的更新,不会触发触发器。 - 当价格涨幅>15%时,你把
ListPrice改回旧值,这确实是一次有效更新,但因为默认递归触发器是关闭的,所以也不会再次触发。
额外提示:你的触发器存在单行依赖问题
当前触发器用变量存储ProductID、新旧价格,只能处理单行更新,如果同时更新多条产品记录,变量会被最后一行的数据覆盖,导致其他行的校验完全失效。建议改成基于集合的操作,避免依赖变量:
CREATE TRIGGER tr_Product_AfterUpdate ON Production.Product AFTER UPDATE AS BEGIN SET NOCOUNT ON; -- 避免返回影响行数的消息 -- 只处理ListPrice被更新的情况 IF UPDATE(ListPrice) BEGIN UPDATE p SET ListPrice = CASE WHEN i.ListPrice - d.ListPrice > d.ListPrice * 0.15 THEN d.ListPrice ELSE i.ListPrice END FROM Production.Product p INNER JOIN deleted d ON p.ProductID = d.ProductID INNER JOIN inserted i ON p.ProductID = i.ProductID END END
内容的提问来源于stack exchange,提问作者DK_bhai
相关产品推荐
相关产品推荐

