Test1插入/更新数据时触发同步Test2对应记录的触发器编写问题
问题分析
原有触发器存在以下几处核心错误:
- 错误1:
SELECT ID INTO v_id1 FROM test1会返回Test1全表的所有ID值,触发「单行子查询返回过多行」的运行异常,完全不需要额外查询Test1,行级触发器可以直接通过:NEW关键字获取当前触发触发器的新行数据。 - 错误2:引用新行字段时没有加冒号前缀,
new.Price1是错误写法,正确应为:NEW.Price1。 - 错误3:仅实现了Test2的更新逻辑,完全没有处理ID不存在时的插入逻辑,不符合需求。
- 错误4:不需要额外声明
v_id1变量,直接使用:NEW.ID即可读取新行的ID值。
修正后的触发器代码
使用Oracle原生MERGE语句可以直接实现「存在则更新、不存在则插入」的Upsert逻辑,无需额外判断:
CREATE OR REPLACE TRIGGER Test_Ord_Update AFTER INSERT OR UPDATE ON Test1 FOR EACH ROW BEGIN MERGE INTO Test2 t2 USING dual ON (t2.ID = :NEW.ID) WHEN MATCHED THEN UPDATE SET t2.Price1 = :NEW.Price1, t2.Price2 = :NEW.Price2 WHEN NOT MATCHED THEN INSERT (ID, Price1, Price2) VALUES (:NEW.ID, :NEW.Price1, :NEW.Price2); END; /
逻辑说明
- 匹配规则为Test2的主键ID等于当前触发触发器的新行ID
- 匹配到ID时,直接更新Test2对应行的Price1、Price2为新行的最新值
- 未匹配到ID时,直接将新行的相关字段插入Test2
- 无需额外查询、变量声明,性能和稳定性更高
内容的提问来源于stack exchange,提问作者vim
相关产品推荐
相关产品推荐

