首页 文章

Oracle 11g中的合并错误

提问于
浏览
0

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

奇怪的是,无论我如何尝试更正语句,即使在此论坛中阅读了许多条目后,我仍然得到完全相同的错误消息 .

有两种不同的错误消息,取决于我在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 time timestamp interval date二进制国家字符nchar

(我到处都是,并没有找到任何答案)

第23行是指“INTO”

  • 但是如果我自己运行上面的Merge语句,而不是作为str的一部分 . proc . ,我没有得到任何错误 . 我得到了一个结果:合并了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 time timestamp interval date二进制国家字符nchar

第23行是指“INTO”

当我将语句作为str的一部分运行时 . PROC:

我得到了一个不同的错误:

命令行出错:9列:8
错误报告:SQL错误:ORA-38104:无法更新ON子句中引用的列:"B" . "LINE_2" 38104. 00000 - "Columns referenced in the ON Clause cannot be updated: %s" 原因:UPDATE SET的LHS包含ON子句动作中引用的列:

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

2 回答

  • 2

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

    您处于这个位置是因为您正在尝试使用MERGE来执行不打算执行的操作 . 现在你说

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

    Fnord . 如果您获得正确的语法,SQL Developer绝对不会阻止您运行更新语句 . 遗憾的是,Oracle不支持DML语句中的ANSI连接语法(与RDBMS的其他flovours不同),并且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
    ;
    
  • 0

    以下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调用相当于说"If this field is not NULL, return it - otherwise return NULL"这有点无意义 .

    祝你好运 .

相关问题