【问题标题】:While updating a column using merge I am getting Error: ORA-38104使用合并更新列时出现错误:ORA-38104
【发布时间】:2018-05-07 03:58:38
【问题描述】:

我正在尝试从下表更新 BUNDLE_NAME, 我的查询是:

MERGE INTO SOURCE S USING 
(SELECT 'MANIFEST_ID' KEY,'CART' BUNDLE_NAME FROM DUAL) D
ON(S.KEY = D.KEY AND S.BUNDLE_NAME = D.BUNDLE_NAME)
WHEN MATCHED THEN UPDATE
SET BUNDLE_NAME = 'EPI';

但它给了我以下错误:

错误报告 - SQL 错误:ORA-38104:无法更新 ON 子句中引用的列:“S”。“BUNDLE_NAME” 38104. 00000 - “不能更新 ON 子句中引用的列:%s” *原因:UPDATE SET 的 LHS 包含 ON 子句中引用的列**

--我的要求是我只想使用合并语句进行更新--

【问题讨论】:

  • 你真的只使用那些固定值,还是这只是一个演示?如果就这么简单,为什么要使用合并而不是更新?
  • 不,其实我只是想知道为什么 ON 子句中引用的列无法更新的原因
  • Because those are the rules *8-) 我想这是为了在所有子句的评估过程中(并行)保持稳定的结果集。

标签: oracle merge


【解决方案1】:

如果您尝试更新它,则不能在 on 子句中包含 bundle_id。由于它是一个固定值,您可以将它放在 where 子句中:

MERGE INTO SOURCE S
USING (SELECT 'MANIFEST_ID' KEY FROM DUAL) D
ON (S.KEY = D.KEY)
WHEN MATCHED THEN UPDATE
SET BUNDLE_NAME = 'EPI'
WHERE S.BUNDLE_NAME = 'CART';

但是你不需要合并,你可以做一个简单的更新:

UPDATE SOURCE S
SET S.BUNDLE_NAME = 'EPI'
WHERE S.KEY = 'MANIFEST_ID'
AND S.BUNDLE_NAME = 'CART';

【讨论】:

  • 关于WHERE 子句,值得一提的是,它似乎并没有从BUNDLE_NAME 上的任何索引中获利,所以UPDATE 语句(或some other workarounds)肯定看起来更可取
【解决方案2】:

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

MERGE INTO SOURCE S USING 
(SELECT 'MANIFEST_ID' KEY,'CART' BUNDLE_NAME FROM DUAL) D
ON(S.KEY = D.KEY AND (S.BUNDLE_NAME, 'dummy') = ((D.BUNDLE_NAME, 'dummy')))
WHEN MATCHED THEN UPDATE
SET BUNDLE_NAME = 'EPI';

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-14
    • 2021-08-31
    • 1970-01-01
    • 2011-08-19
    • 2014-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多