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

Oracle MERGE INTO单表Upsert报错ORA-38104求助

问题原因与解决办法

错误根源

ORA-38104错误的核心原因是:你在MERGE语句的ON匹配条件里,包含了要更新的Passed字段。Oracle明确规定,MERGE的匹配条件中引用的列,不允许在when matched then update里被修改。

另外你的原逻辑也不符合需求:需求是根据Name、Surname、Age判断学生是否存在,而不是把Passed也作为存在判断的依据——如果同一个学生的Passed状态变化,原逻辑会把它当成新行插入,而不是更新。

修正方案

1. 修正MERGE SQL语句

去掉ON条件中的t.PASSED=s.PASSED,只保留Name、Surname、Age作为存在判断依据:

merge into student t
using (
    select
        ? AS NAME,
        ? AS SURNAME,
        ? AS AGE,
        ? AS PASSED
    from
        dual
) s on (
    t.NAME = s.NAME
    and t.SURNAME = s.SURNAME
    and t.AGE = s.AGE
)
when matched then 
    update set t.PASSED = s.PASSED 
when not matched then 
    insert (NAME, SURNAME, AGE, PASSED) values (s.NAME, s.SURNAME, s.AGE, s.PASSED);

2. 修正JdbcTemplate代码

代码里存在两处拼写/语法错误,需要一并修正:

  • PreparedStatment 拼写错误,应为PreparedStatement
  • getBatchSize()方法末尾缺少分号
  • 方法需要声明抛出SQLException

修正后的代码:

jdbcTemplate.batchUpdate(query, new BatchPreparedStatementSetter() {

    @Override
    public void setValues(PreparedStatement ps, int i) throws SQLException {
        Student s = studentList.get(i);

        ps.setString(1, s.getName());
        ps.setString(2, s.getSurname());
        ps.setInt(3, s.getAge());
        ps.setString(4, s.getPassed());
    }

    @Override
    public int getBatchSize() {
        return studentList.size();
    }

});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 16:52:16