【问题标题】:Oracle - ORA-38101: Invalid column in the INSERT VALUES Clause on MergeOracle - ORA-38101:合并时的 INSERT VALUES 子句中的列无效
【发布时间】: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


【解决方案1】:
  • 不要使用与表列名相同的变量名。

  • 你的MATCHED 子句什么也没做。

  • USING子句中,一定有评论中提到的一些查询。

【讨论】:

  • 好的,是的。我通过在 USING 部分添加查询来解决它,并且还必须在字段中添加带有 AS 的别名。
猜你喜欢
  • 1970-01-01
  • 2015-05-06
  • 1970-01-01
  • 1970-01-01
  • 2015-04-11
  • 2013-06-07
  • 2019-03-30
  • 2017-05-12
  • 1970-01-01
相关资源
最近更新 更多