SQL如何避免ora-38104?

SQL如何避免ora-38104?,sql,oracle,merge,Sql,Oracle,Merge,我想更新大表TEMP\u MA\u CONTACT,并使用合并到: 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 th

我想更新大表
TEMP\u MA\u CONTACT
,并使用
合并到

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

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

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

解决此问题的最佳方案是:

1) 首先将rowid添加到表\u以更改\u 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
。似乎保留原始查询的性能特征(允许在
CUSTOMER\r k
列上使用索引)的解决方法之一是使用行值表达式:

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之前,这似乎一直有效,您根本不需要
合并
。将一个列设置为它已经拥有的值。是的,但是它会非常慢,您会考虑添加一个列,它是ID列的精确副本,通过它进行比较,然后删除列?@Jdzel用我的答案编辑了我的答案suggestion@Jdzel:是什么让你认为更新会比合并慢?两者都在执行相同的工作。我可能只在一个表中添加一列:table\u to\u change_2601@BobJarvis因为子查询