假设我有一个 Oracle 数据库,其中有一个名为 RUN_LOG
的表我用来记录作业何时执行。
该表有一个主键JOB_NAME
它唯一标识已执行的作业,以及名为 LAST_RUN_TIMESTAMP
的列这反射(reflect)了上次执行作业的时间。
当作业开始时,我想更新作业的现有行(如果存在),或者以其他方式将新行插入表中。
鉴于 Oracle 不支持 REPLACE INTO
式查询,有必要尝试 UPDATE
,如果零行受到影响,则使用 INSERT
跟进.
这通常是通过 jdbc 使用如下内容实现的:
PreparedStatement updateStatement = connection.prepareStatement("UPDATE ...");
PreparedStatement insertStatement = connection.prepareStatement("INSERT ...");
updateStatement.setString(1, "JobName");
updateStatement.setTimestamp(2, timestamp);
// If there are no rows to update, it must be a new job...
if (updateStatement.executeUpdate() == 0) {
// Follow-up
insertStatement.setString(1, "JobName");
insertStatement.setTimestamp(2, timestamp);
insertStatement.executeUpdate();
}
这是一条相当成熟的道路,我对这种方法非常满意。
但是,假设我的用例要求我插入大量此类记录。对数据库执行单独的 SQL 查询太“啰嗦”了。相反,我想开始批处理这些 INSERT
/UPDATE
查询
鉴于 UPDATE
的执行查询将推迟到批处理提交后,我无法观察到有多少行受到影响。
实现此目标的最佳机制是什么 REPLACE INTO
- 样的结果?
我宁愿避免使用存储过程,因为我宁愿将我的持久性逻辑保留在这个地方(类),而不是将其分布在 Java 代码和数据库之间。
最佳答案
SQL MERGE 语句呢?您可以向临时表插入大量记录,然后将临时表与 RUN_LOG 合并 例如:
merge into RUN_LOG tgt using (
select job_name, timestamp
from my_new_temp_table
) src
on (src.job_name = tgt.job_name)
when matched then update set
tgt.timestamp = src.timestamp
when not matched then insert values (src.job_name, src.timestamp)
;
关于java - 针对 Oracle 数据库的批处理 "UPDATE vs. INSERT"查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41012888/