You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带delete子句的MERGE配合触发器为何触发ORA-30926错误?

问题复现准备

准备用于复现问题的schema如下:

create table t (id int, val int, modified timestamp default systimestamp)
/
create or replace trigger trigg_on_t  
before update on t for each row enable  
begin  
    :new.modified := systimestamp;  
end;
/
insert into t (id, val) values (1, 1);
commit;
报错触发场景

当目标表上定义了上述BEFORE UPDATE行级触发器时,执行带DELETE子句的MERGE语句会触发错误,测试SQL如下:

merge into t  
using (  
    select 1 id, 10 val, 1 flag from dual  
) s on (t.id = s.id)  
when matched then  
    update set t.val=s.val  
    delete where s.flag=1

执行后返回报错:

ORA-30926: unable to get a stable set of rows in the source tables

30926, 00000, "unable to get a stable set of rows in the source tables"
// *原因:大量DML操作或非确定性where子句导致无法获取稳定的源表行集
// *解决方案:移除所有非确定性where子句后重新执行DML。

核心疑问:
该场景下的执行逻辑存在什么问题?报错提示中提到的非确定性where子句究竟出现在哪里?


对照验证结果

经测试,以下两种操作都可以让上述MERGE语句正常执行,不会触发报错:

-- 方式1:在update子句中显式设置timestamp字段取值
merge into t  
using (  
    select 1 id, 1 val, 1 flag from dual  
) s on (t.id = s.id)  
when matched then  
    update set t.val=s.val, modified=systimestamp    
    delete where s.flag=1
/
-- 执行结果:1 row merged.

rollback;
-- 方式2:禁用表上的触发器
alter trigger trigg_on_t disable;

merge into t  
using (  
    select 1 id, 1 val, 1 flag from dual  
) s on (t.id = s.id)  
when matched then  
    update set t.val=s.val  
    delete where s.flag=1
/
-- 执行结果:1 row merged.
根因说明

这个场景下不存在用户手写的非确定性WHERE子句,报错本质是触发器的副作用触发了Oracle的MERGE行集稳定性校验:

  1. 带DELETE子句的MERGE执行逻辑中,Oracle完成MATCHED分支的UPDATE操作后,会重新读取被更新的目标行,校验该行是否满足DELETE的过滤条件。
  2. 测试用的BEFORE UPDATE行级触发器,会在每次更新行时调用systimestamp给modified字段赋值——systimestamp是随调用时间变化的非确定性函数,触发器的修改不属于MERGE语句本身声明的字段更新逻辑,Oracle在重流行做DELETE校验时,会检测到同一行的modified字段取值和UPDATE执行阶段的计算结果不一致,判定目标行集不稳定,最终抛出ORA-30926错误。
  3. 两种规避方案生效的原因也很明确:
    • 显式在UPDATE子句中设置modified字段取值时,Oracle将该字段的修改纳入MERGE本身的执行逻辑,不会判定为预期外的行值变动
    • 禁用触发器后,不存在额外的行值修改逻辑,行集稳定性校验自然可以通过

内容的提问来源于stack exchange,提问作者0xdb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 07:15:33