ORA-38104:UPDATE SET的LHS包含ON子句中引用的列

时间:2017-09-01 12:55:00

标签: sql oracle ora-38104

我需要更新(D.SELLER_ACCOUNT_ID = S.ACCOUNT_ID AND D.CATEGORY_ID = S.CATEGORY_ID_OLD)上的行。

如何在Oracle中更正下面的查询?

MERGE INTO T_EVM_CLASSIFICATION D
   USING (SELECT CATEGORY_ID_NEW, CATEGORY_ID_OLD, ACCOUNT_ID FROM DATA_TEMP) S
   ON (D.SELLER_ACCOUNT_ID = S.ACCOUNT_ID AND D.CATEGORY_ID = S.CATEGORY_ID_OLD)
   WHEN MATCHED THEN UPDATE SET D.CATEGORY_ID = S.CATEGORY_ID_NEW;

3 个答案:

答案 0 :(得分:2)

将“违规”条件从ON子句移到WHERE子句:

MERGE INTO T_EVM_CLASSIFICATION D
   USING (SELECT CATEGORY_ID_NEW, CATEGORY_ID_OLD, ACCOUNT_ID FROM DATA_TEMP) S
   ON (D.SELLER_ACCOUNT_ID = S.ACCOUNT_ID)
   WHEN MATCHED THEN UPDATE SET   D.CATEGORY_ID = S.CATEGORY_ID_NEW
                            WHERE D.CATEGORY_ID = S.CATEGORY_ID_OLD;

答案 1 :(得分:1)

如果有1:1的关系,请使用简单的update

update t_evm_classification d set category_id = (
  select category_id_new 
    from data_temp s
    where d.seller_account_id = s.account_id 
      and d.category_id = s.category_id_old )

如果临时表中的数据不存在,则上述更新将使category_id无效。为了避免这种情况,请添加where子句:

update t_evm_classification d 
  set category_id = ( select category_id_new 
                        from data_temp s
                       where d.seller_account_id = s.account_id 
                         and d.category_id = s.category_id_old )
  where (d.seller_account_id, d.category_id) in 
    (select s.account_id, category_id_old from data_temp s)

答案 2 :(得分:0)

There are a few possible workarounds which can be used to outsmart the parser,至少直到Oracle 18c。其中之一是使用附加的伪列将谓词包装在行值表达式谓词中:

MERGE INTO T_EVM_CLASSIFICATION D
   USING (SELECT CATEGORY_ID_NEW, CATEGORY_ID_OLD, ACCOUNT_ID FROM DATA_TEMP) S
   ON (D.SELLER_ACCOUNT_ID = S.ACCOUNT_ID 
     AND (D.CATEGORY_ID, 'dummy') = ((S.CATEGORY_ID_OLD, 'dummy')))
   WHEN MATCHED THEN UPDATE SET D.CATEGORY_ID = S.CATEGORY_ID_NEW;