【发布时间】:2021-03-02 02:30:45
【问题描述】:
我正在尝试使用合并进行更新插入,但我收到一条错误消息:Oracle - ORA-38101: Invalid column in the INSERT VALUES Clause on Merge: "MY_TABLE"."MYCOL2",即使错误中指示的表和列名称是正确的。
declare
var1 varchar2(50) := 'var1';
var2 varchar2(50) := 'var2';
procedure ins
(mycol1 IN VARCHAR2,
mycol2 IN VARCHAR2)
is
BEGIN
LOOP
BEGIN
MERGE INTO my_table USING dual ON
( MYCOL1 = mycol1
AND MYCOL2 = mycol2
)
WHEN MATCHED THEN UPDATE SET
MYCOL1 = mycol1,
MYCOL2 = mycol2
WHEN NOT MATCHED THEN INSERT
(MYCOL1, MYCOL2)
VALUES ( mycol1, mycol2 );
EXIT; -- success? -> exit loop
EXCEPTION
WHEN NO_DATA_FOUND THEN -- the entry was concurrently deleted
NULL; -- exception? -> no op, i.e. continue looping
WHEN DUP_VAL_ON_INDEX THEN -- an entry was concurrently inserted
NULL; -- exception? -> no op, i.e. continue looping
END;
END LOOP;
END;
begin
ins (var1, var2);
end;
【问题讨论】:
-
你需要一个 子查询 例如
MERGE INTO my_table USING ( SELECT <some_val> AS mycol1, <some_val> AS mycol2 dual ) ON而不是MERGE INTO my_table USING dual ON... -
@Tejash 是绝对正确的,但稍微解释一下可能会有所帮助。 Oracle 对名称(表、视图、变量...)不区分大小写,除非双引号。因此MYCOL1 和mycol1 是相同的。并且始终选择表列而不是变量,因此您的更新只会将列设置为其当前值。此外,您还有逻辑问题。您有一个 MERGE 在其中运行的循环。但是您的数据值在循环期间不会更改,因此如果您选择 MATCHED 腿,您的循环将永远不会结束。 MERGE 是单个 DML 语句,除非数据发生变化,否则不应处于循环中。
标签: database oracle plsql upsert