Oracle MERGE引发ORA-00904错误

时间:2011-11-25 08:36:22

标签: oracle merge ora-00904

我正在使用merge命令将不存在的记录插入表中。当我使用简单的插入命令时,它工作正常。如果我使用合并系统总是警告ORA-00904:“T”。“GROUP_COMPANY_ID”无效的标识符。一旦我将ON条件更改为(1 = 1)以强制为true,则merge命令正常工作。

原始合并声明出错了什么?我非常确定该表是在没有双引号的情况下创建的,所以这里没有案例问题。

create table test
(
  create_date      DATE not null,
  group_company_id CHAR(16) not null
)

-- This is okay
INSERT INTO test (create_date, group_company_id) VALUES (TO_DATE('20100531', 'YYYYMMDD'), 'abc');

-- This one will raise ORA-00904 error
MERGE INTO test T
USING (SELECT 'abc' AS group_company_id FROM DUAL) C
   ON (T.group_company_id = C.group_company_id)
-- ON (1 = 1)
WHEN NOT MATCHED THEN
     INSERT (create_date, group_company_id)
     VALUES (TO_DATE('20100531', 'YYYYMMDD'), 'abc')
WHEN MATCHED THEN
     UPDATE SET group_company_id = 'abc';

3 个答案:

答案 0 :(得分:8)

您无法更新要加入的列。

答案 1 :(得分:1)

你的代码不会抛出ORA-00904,它会引发不言自明的ORA-38104

SQL> MERGE INTO test T
USING (SELECT 'abc' AS group_company_id FROM DUAL) C
   ON (T.group_company_id = C.group_company_id)
-- ON (1 = 1)
WHEN NOT MATCHED THEN
     INSERT (create_date, group_company_id)
     VALUES (TO_DATE('20100531', 'YYYYMMDD'), 'abc')
WHEN MATCHED THEN
     UPDATE SET group_company_id = 'abc';
  2    3    4    5    6    7    8    9     ON (T.group_company_id = C.group_company_id)
       *
ERROR at line 3:
ORA-38104: Columns referenced in the ON Clause cannot be updated:
"T"."GROUP_COMPANY_ID"


SQL> 

我正在运行11gR2 - 也许早期版本的行为有所不同。无论如何,解决方案非常简单:不要打扰MATCHED分支:

SQL> MERGE INTO test T
USING (SELECT 'abc' AS group_company_id FROM DUAL) C
   ON (T.group_company_id = C.group_company_id)
-- ON (1 = 1)
WHEN NOT MATCHED THEN
     INSERT (create_date, group_company_id)
     VALUES (TO_DATE('20100531', 'YYYYMMDD'), 'abc')
  2    3    4    5    6    7    8  /

0 rows merged.

SQL> 

当在9i中引入MERGE时,此语法无效:我们必须包含两个分支。但它从10g开始就得到了支持。

如果您使用的是9i,那么需要一个MATCHED分支,您必须更新一个未包含在join子句中的列。那将是你的例子中的CREATE_DATE,

答案 2 :(得分:0)

使用insertupdate子句中的表格ai来限定列名称

WHEN NOT MATCHED THEN
  INSERT (T.create_date, T.group_company_id)
  VALUES (TO_DATE('20100531', 'YYYYMMDD'), 'abc')
WHEN MATCHED THEN
  UPDATE SET T.group_company_id = 'abc'; 

编辑:

MERGE INTO test  
USING DUAL   
ON (group_company_id = 'abc') 
WHEN NOT MATCHED THEN      
      INSERT VALUES (TO_DATE('20100531', 'YYYYMMDD'), 'abc');