0

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

原来的合并语句出了什么问题?我非常确定该表是在没有双引号名称的情况下创建的,因此这里没有大小写问题。

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';
4

3 回答 3

8

您无法更新要加入的列。

于 2011-11-25T08:49:30.673 回答
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 分支,则必须更新未包含在连接子句中的列。在您的示例中,这将是 CREATE_DATE,

于 2011-11-25T11:09:56.810 回答
0

insert用andupdate子句中的表别名来限定列名

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');
于 2011-11-25T08:53:41.793 回答