Oracle 11g 中的合并错误

Posted

技术标签:

【中文标题】Oracle 11g 中的合并错误【英文标题】:Merge error in Oracle 11g 【发布时间】:2012-07-27 18:12:21 【问题描述】:

我是 Oracle 11g 和这个论坛的新手。我只需要使用 Oracle Merge 语句运行一个简单的更新语句,因为我的 SQL 开发人员不会采取任何其他方式。

奇怪的是,无论我如何尝试更正该声明,即使在阅读了该论坛中的许多条目后,我仍然收到完全相同的错误消息。

有 2 种不同的错误消息,取决于我在 SQL Developer 中运行语句的方式。如果我将我的语句作为存储过程运行(更新语句是存储过程中的一小部分。我注释掉了其他 SQL 语句,只是将这个更新语句留在了存储过程中)我得到了这个错误:

我跑了这个:

create or replace
PROCEDURE ADDR_UPDATE_2
AS
/*     other sql statements are commented out    */  

MERGE INTO (SELECT id,xseq,line_1,line_2,zip,tax FROM ADDR ) b
USING (SELECT id,xseq,line_1, line_2,NVL(zip, '') AS pos_10 , NVL(tax, '') AS pos_11
     FROM TEMP_ADDR ) v
ON(b.id = v.id
  AND b.xseq = v.xseq)  
WHEN MATCHED THEN UPDATE SET b.line_1 = v.line_1,
                          b.line_2 = v.line_2,                            
                          b.zip = v.pos_10,
                          b.tax = v.pos_11
                          WHERE b.line_1 <> v.line_1  
                          OR b.line_2 <> v.line_2
                          OR b.zip <> v.pos_10; 

/*     other sql statements are commented out   */

END;

我得到了这个错误:

错误(23,9):PLS-00103:在预期以下之一时遇到符号“INTO”:常量异常表 long double ref char 时间时间戳间隔日期二进制国家字符 nchar

(我到处看,没有找到任何答案)

第 23 行指的是“INTO”这个词

但如果我单独运行上述 Merge 语句,而不是作为 str 的一部分。过程, 我没有收到任何错误。我得到了一个结果:0 行合并。

现在我将 Merge 语句修改为:

create or replace
PROCEDURE ADDR_UPDATE_2
AS

/*  other sql statements are commented out  */  

MERGE INTO ADDR b
USING (SELECT id,xseq, line_1, line_2, NVL(zip, '') AS pos_10, 
            NVL(tax, '') AS pos_11 
     FROM TEMP_ADDR) v
 ON(b.id = v.id
    AND b.xseq = v.xseq
    AND b.line_1 <> v.line_1  
    OR b.line_2 <> v.line_2 
    OR  b.zip <> v.pos_10)  
 WHEN MATCHED THEN UPDATE SET b.line_1 = v.line_1,
                          b.line_2 = v.line_2,
                          b.zip = v.pos_10,
                          b.tax = v.pos_11;

 /*
   other sql statements are commented out
 */

END;

我遇到了同样的错误:

错误(23,9):PLS-00103:在预期以下之一时遇到符号“INTO”:常量异常表 long double ref char 时间时间戳间隔日期二进制国家字符 nchar

第 23 行指的是“INTO”这个词

当我不作为 str 的一部分运行语句时。过程:

我得到一个不同的错误:

命令行错误:9 列:8 错误报告: SQL 错误:ORA-38104:无法更新 ON 子句中引用的列:“B”。“LINE_2” 38104. 00000 - “不能更新 ON 子句中引用的列:%s” *原因:UPDATE SET 的 LHS 包含 ON 子句中引用的列 *行动:

我从2天前开始尝试寻找答案,但没有结果,有没有人可以帮助解决这个问题?

【问题讨论】:

在“CREATE OR REPLACE PROCEDURE ADDR_UPDATE_2”之后缺少“BEGIN”。 天哪!!!谢谢你!!它有效! Oracle MERGE raise ORA-00904 error的可能重复 【参考方案1】:

正如我在上面提到的问题中解释的那样,“不能更新 ON 子句中引用的列”意味着如果 MATCHED 子句中的列包含在 ON 条件中,我们将无法更新它们。

你处于这个位置是因为你试图使用 MERGE 来做一些它不打算做的事情。现在你说

"我只需要使用 Oracle Merge 运行一个简单的更新语句 声明,因为我的 SQL 开发人员不会采取任何其他方式。”

福特。 SQL Developer 绝对不会阻止您运行更新语句只要语法正确。不幸的是,Oracle 不支持 DML 语句中的 ANSI 连接语法(与其他 RDBMS 不同),并且 Oracle 语法不直观:

update
(
   select v.id
          , v.xseq
          , v.line_1
          , v.line_2
          , nvl(v.zip, '') AS pos_10
          , nvl(v.tax, '') AS pos_11
   from   addr b
         ,temp_addr v
   where  ( b.id = v.id
            and b.xseq = v.xseq )
      and ( b.line_1 <> v.line_1  
            or  b.line_2 <> v.line_2 
            or  b.zip <> v.pos_10)
     )
set b.line_1 = v.line_1,
    b.line_2 = v.line_2,
    b.zip = v.pos_10,
    b.tax = v.pos_11
;

【讨论】:

【参考方案2】:

以下 MERGE 语句至少应该可以正确编译和执行,尽管我同意 @APC 的观点,这里正确的做法是使用 UPDATE(因为这是您真正想要做的):

MERGE INTO ADDR b
USING TEMP_ADDR v
  ON (b.id = v.id AND
      b.xseq = v.xseq)  
WHEN MATCHED THEN
  UPDATE
    SET b.line_1 = v.line_1,
        b.line_2 = v.line_2,                            
        b.zip = v.zip,
        b.tax = v.tax;

我消除了您正在执行的 NVL 操作,因为在 Oracle 中,零长度字符串(例如 '')与 NULL 相同,因此 NVL 调用相当于说“如果此字段不为 NULL,则返回它 - 否则返回 NULL",这是毫无意义的。

祝你好运。

【讨论】:

以上是关于Oracle 11g 中的合并错误的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 11g 连接重置错误

oracle11g 安装错误汇总

在装oracle 11g的时候出现 由于以下错误,Enterprise Manager 配置失败:

Oracle 11g 无效标识符错误

oracle11g 安装错误[INS30131],win10系统

为啥安装oracle11g的时候总是应用程序错误