【问题标题】:SQL How can I avoid ora-38104?SQL 如何避免 ora-38104?
【发布时间】:2016-05-02 23:36:17
【问题描述】:

我想更新大表TEMP_MA_CONTACT,我用MERGE INTO

MERGE INTO TEMP_MA_CONTACT C
USING (select * from TABLE_TO_CHANGE_2601) T
ON (C.CUSTOMER_RK = T.CUSTOMER_RK)
WHEN MATCHED THEN UPDATE SET C.CUSTOMER_RK = T.NEW_CUSTOMER_RK

但甲骨文说:

ORA-38104: Columns referenced in the ON Clause cannot be updated

【问题讨论】:

  • 您根本不需要merge。您正在将一列设置为它已有的值。

标签: sql oracle merge


【解决方案1】:

嗯,我不确定合并是否可行。但您始终可以将更新与子查询一起使用:

UPDATE TEMP_MA_CONTACT C
set c.customer_rk =
(select P.new_customer_rk from table_to_change_2601 p where P.customer_rk = C.customer_rk)

另一个想法是这样的:

ALTER TABLE TEMP_MA_CONTACT add TEMP_COL NUMBER(5);
UPDATE TEMP_MA_CONTACT set TEMP_COL = customer_rk;

然后使用你原来的合并,但是在这个列上是这样的:

MERGE INTO TEMP_MA_CONTACT C
USING (select * from TABLE_TO_CHANGE_2601) T
ON (C.TEMP_COLUMN = T.CUSTOMER_RK)
WHEN MATCHED THEN UPDATE SET C.CUSTOMER_RK = T.NEW_CUSTOMER_RK;
commit;

然后删除列

ALTER TABLE TEMP_MA_CONTACT drop column TEMP_COLUMN

【讨论】:

  • 可以,但是会很慢
  • 您是否考虑添加一个与 ID 列完全相同的列,通过它进行比较,然后删除该列? @Jdzel 用我的建议编辑了我的答案
  • @Jdzel:是什么让您认为 UPDATE 会比 MERGE 慢?两者都在执行相同的工作。
  • 我可能只在一个表中添加一列:table_to_change_2601
  • @BobJarvis 因为子查询
【解决方案2】:

解决此问题的最佳变体是:

1) 首先将rowid添加到table_to_change_2601

    CREATE TABLE table_to_change_2601_new AS 
SELECT T.*,
I.ROWID AS ROW_ID FROM
        table_to_change_2601 T JOIN temp_ma_contact I ON T.CUSTOMER_RK = I.CUSTOMER_RK

2) 在这个 rowid 上合并

MERGE INTO temp_ma_contact C
USING (select * from table_to_change_2601_new) T
ON (C.ROWID = T.ROW_ID)
WHEN MATCHED THEN UPDATE SET C.CUSTOMER_RK = T.NEW_CUSTOMER_RK

【讨论】:

    【解决方案3】:

    There are a few workarounds that I have described in this blog post here。似乎保留原始查询的性能特征(允许在CUSTOMER_RK 列上使用索引)的解决方法之一是使用行值表达式:

    MERGE INTO TEMP_MA_CONTACT C
    USING (select * from TABLE_TO_CHANGE_2601) T
    ON ((C.CUSTOMER_RK, 'dummy') = ((T.CUSTOMER_RK, 'dummy')))
    WHEN MATCHED THEN UPDATE SET C.CUSTOMER_RK = T.NEW_CUSTOMER_RK
    

    这似乎一直有效到 Oracle 18c

    【讨论】:

      猜你喜欢
      • 2011-12-14
      • 1970-01-01
      • 2013-06-07
      • 2021-08-31
      • 2012-04-26
      • 1970-01-01
      • 2011-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多