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拼写错误,应为PreparedStatementgetBatchSize()方法末尾缺少分号- 方法需要声明抛出
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
相关产品推荐
相关产品推荐

