SQL Server创建STATUS更新时自动更新DATE_STATUS触发器报错如何解决
错误原因
你的代码核心问题出在WHERE条件的写法:
- SQL Server触发器中的
INSERTED和DELETED是保存更新前后全量数据的临时表,当单次更新操作修改多行时,两个表内都会存在多条记录。你写的(SELECT STATUS FROM INSERTED) <> (SELECT STATUS FROM DELETED)属于标量子查询,在多行场景下会返回多个值,无法进行标量比较,因此抛出多行相关的报错。 - 该写法也无法逐行判断每行的STATUS是否真的发生了修改,就算不报错也会出现逻辑错误。
修正后的触发器代码
CREATE TRIGGER AFTER_UPDATE_STATUS ON ORDER_TEST AFTER UPDATE AS BEGIN -- 若更新的字段不包含STATUS,直接跳过触发器逻辑 IF NOT UPDATE(STATUS) RETURN UPDATE ot SET DATE_STATUS = GETDATE() FROM ORDER_TEST ot INNER JOIN INSERTED i ON ot.[№] = i.[№] INNER JOIN DELETED d ON i.[№] = d.[№] -- 逐行对比STATUS是否真的发生变化,仅修改符合条件的行 WHERE i.STATUS <> d.STATUS END
补充说明
- 前置的
IF NOT UPDATE(STATUS)判断可以避免更新其他字段时触发不必要的逻辑,降低性能消耗。 - 用SQL Server原生的
GETDATE()替代{fn now()}兼容性更好,二者功能完全一致,均返回当前系统时间。 - 逐行关联
INSERTED和DELETED的判断逻辑,既兼容单行更新也兼容批量更新场景,不会再出现多行报错问题。
内容的提问来源于stack exchange,提问作者Егор Кравченко
相关产品推荐
相关产品推荐

