在SQL Server触发器中如何获取未变更行?验证语句可行性
SQL Server触发器相关问题解答
1. 如何选择触发器执行后表内未发生变更的行?
要获取未变更的行,本质就是找出没被本次触发器操作影响的记录,具体分场景处理:
- 若是
UPDATE或DELETE操作:用触发器所在基表的ID,排除DELETED表里的ID,剩下的就是未变更行 - 若是
INSERT操作:此时DELETED表为空,需要用基表ID排除INSERTED表里的ID,得到未变更行
2. 你提供的SQL语句是否可行?
先贴出你给出的语句:
SELECT * FROM DELETED UNION SELECT * FROM Table WHERE Table.Id NOT IN (SELECT Id FROM DELETED)
这条语句逻辑上能实现获取变更行旧值+未变更行的需求,但有几个坑要注意:
- 性能问题:
NOT IN在数据量大时效率较差,建议换成LEFT JOIN写法,同时用UNION ALL替代UNION(因为两边数据不会重复,无需去重,性能更优):SELECT d.* FROM DELETED d UNION ALL SELECT t.* FROM [Table] t LEFT JOIN DELETED d ON t.Id = d.Id WHERE d.Id IS NULL - 语法问题:
Table是SQL Server的保留字,作为表名必须用方括号[Table]括起来,否则会触发语法错误 - 场景限制:这条语句仅适用于
UPDATE或DELETE触发器;如果是INSERT触发器,DELETED表为空,语句会返回整个基表的数据,不符合预期。针对INSERT场景,需改成对比INSERTED表:SELECT * FROM INSERTED UNION ALL SELECT t.* FROM [Table] t LEFT JOIN INSERTED i ON t.Id = i.Id WHERE i.Id IS NULL
内容的提问来源于stack exchange,提问作者GoncaloCC
相关产品推荐
相关产品推荐

