我正在使用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';
答案 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)
使用insert
和update
子句中的表格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');