jwa*_*jwa 1 java database oracle jdbc
假设我有一个Oracle数据库,其中有一个表,RUN_LOG我正在使用它来记录作业执行的时间.
该表具有JOB_NAME唯一标识已执行作业的主键,以及一个LAST_RUN_TIMESTAMP在上次执行作业时反映的列.
作业启动时,我想更新作业的现有行(如果存在),或者在表中插入新行.
鉴于Oracle不支持a- REPLACE INTOstyle查询,有必要尝试一个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();
}
Run Code Online (Sandbox Code Playgroud)
这是一条相当完善的道路,我对这种方法非常满意.
但是,我们假设我的用例要求我插入大量的这些记录.对数据库执行单独的SQL查询将太"唠叨".相反,我想开始批处理这些INSERT/ UPDATE查询
鉴于UPDATE查询的执行将被推迟到批处理提交之前,我无法观察到在以后的日期有多少行受到影响.
实现这种REPLACE INTO结果的最佳机制是什么?
我宁愿避免使用存储过程,因为我更喜欢将持久性逻辑保留在这个地方(类),而不是在Java代码和数据库之间分配.
小智 5
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)
;
Run Code Online (Sandbox Code Playgroud)