java - 针对 Oracle 数据库的批处理 "UPDATE vs. INSERT"查询

标签 java database oracle jdbc

假设我有一个 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/

相关文章:

java - 修改 Spring 消息文本而不重新启动应用程序?

java - 我需要帮助完成作业

database - 创建太多数据库索引的权衡是什么?

c# - cosmos db 中的异步查询

java - 查询在 SQL*Plus 中有效,但在 JDBC 中失败并出现 ORA-00911 异常

oracle - 是否可以使用 OData 从 Oracle 公开数据?

java - 使用 Spring Mvc WebApplicationInitializer,但未找到 HTTP 请求的映射

java - JDBC:PreparedStatement.cancel() 的正确行为是什么

sql - 在 sql 中没有任何 while 循环的情况下从列中删除前导零

sql - 在 Oracle 正则表达式查询中转义单引号