如何合并两个更新查询作为Oracle中的单个更新查询



table1具有ID和ref_id为复合主键,下面给定查询更新100列

Update table1 
set contri_status = 0 
where status = 1 
  and acc_dr_status = 1 
  and contri_status = 1 
  and id = '111';

下面给定查询更新3列

Update table1 
set acc_dr_status = 50 
where  status = 1 
  and acc_dr_status = 1 
  and contri_status = 0 
  and id = '111' 
  and ref_id in ('1','2','3');

我希望单个查询在两个任务上执行两个任务,因此在下面给定的查询

Update table1 
set  contri_status = 0
   , acc_dr_status = 50    
where status = 1 
  and acc_dr_status = 1 
  and contri_status = 1 
  and id = '111' 
  and ref_id in ('1','2','3');

第二个更新的查询列conti_status在第一个查询更新上依赖。第一个修改的行是唯一要通过第二查询修改的一行(如果修改100,则第一个查询,然后第二行将达到10行,因为我在(...)子句中使用ref_id的exture ref_id)。在两个主要上升日期查询的子句条件的情况下,要更新的单个查询应满足

的条款条件。

无法获得适当的结果。

注意:每个由OP提供的其他详细信息(在评论 - 请参见下文;还添加到问题),2x更新串行运行,更新#2仅影响影响行的一部分通过更新#1。

update table1
set    contri_status = 0,
                    /* case statement limits acc_dr_status update to rows
                       limited by update #2
                    */
       acc_dr_status = case when ref_id in ('1','2','3') 
                            then 50 
                            else acc_dr_status      /* (re)set to its current value */
                       end
/* where clause finds all rows desired by update #1 */
where  status        = 1
and    acc_dr_status = 1
and    contri_status = 1
and    id            = '111'

潜在的缺点(重新)将contri_statusacc_dr_status列设置为当前值:

  • 额外写入日志
  • 额外的复制开销(如果复制)
  • 不必要/不希望的触发活动(可能需要重新编码触发器以解决这些方案)

注意:基于原始问题和(我的)假设的第一个答案,两个更新之间没有依赖关系。

一般来说您可以:

  • 组合where条款
  • 使用基于单独的where条件的case语句进行有条件设置列

使用以上的一种可能的update语句:

update table1
                    /* case statement 'when' clauses should match
                       the corresponding (distinct) where clauses 
                    */
set    contri_status = case when contri_status = 1 
                            then 0 
                            else contri_status      /* (re)set to its current value */
                       end,
       acc_dr_status = case when contri_status = 0 and ref_id in ('1','2','3') 
                            then 50 
                            else acc_dr_status      /* (re)set to its current value */
                       end
/* common where clauses */
where  status        = 1
and    acc_dr_status = 1
and    id            = '111'
/* distinct where clauses */
and    (    contri_status = 1
        or (contri_status = 0 and ref_id in ('1','2','3'))
       )

相同的潜在弊端适用于:(re)设置具有相同值的contri_statusacc_dr_status列。

我已经使用了案例语句来更新,希望这会起作用。

<i>UPDATE TABLE1 SET CONTRI_STATUS = (CASE WHEN CONTRI_STATUS = 1 THEN 0 ELSE CONTRI_STATUS END), 
                     ACC_DR_STATUS = (CASE WHEN CONTRI_STATUS = 0 AND REF_ID IN ('1','2','3') THEN 50 ELSE ACC_DR_STATUS END)
WHERE STATUS = 1 AND ACC_DR_STATUS = 1 AND ID = 111</i>