批处理"更新与插入"针对Oracle数据库的查询

时间:2016-12-07 08:45:55

标签: java database oracle jdbc

假设我有一个Oracle数据库,其中包含一个名为if let url = URL(string: urlString) { Alamofire.download(url).responseData(completionHandler: { response in if response.result.isSuccess { if let plistData = response.result.value { if let plistXml = String(data: data, encoding: .utf8) { // plistXml contains the actual plist contents as String object. } } } }) } 的表,我用它来记录作业执行的时间。

该表有一个主键RUN_LOG,它唯一地标识已执行的作业,以及一个名为JOB_NAME的列,它反映了上次执行作业的时间。

当作业开始时,我想更新作业的现有行(如果存在),或者在表中插入新行。

鉴于Oracle不支持LAST_RUN_TIMESTAMP样式的查询,有必要尝试REPLACE INTO,如果零行受到影响,请使用UPDATE跟进此行。

这通常通过jdbc使用以下内容实现:

INSERT

这是一条相当完善的道路,我对这种方法非常满意。

但是,让我们假设我的用例要求我插入大量的这些记录。对数据库执行单独的SQL查询也太过分了。#34; chatty"。相反,我想开始批量处理这些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(); } / INSERT个查询

鉴于UPDATE查询的执行将推迟到批处理提交之前,我无法观察到有多少行会受到影响,直到稍后的日期。

实现此UPDATE的最佳机制是什么?

我宁愿避免使用存储过程,因为我更喜欢将持久性逻辑保留在这个地方(类),而不是在Java代码和数据库之间分发。

1 个答案:

答案 0 :(得分: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)
;