【问题标题】:Oracle Procedure Errors PLS-00330, ORA-00904: : invalid identifier, and Error(37,24): PLS-00382Oracle 过程错误 PLS-00330、ORA-00904: : invalid identifier 和 Error(37,24): PLS-00382
【发布时间】:2016-07-29 14:35:04
【问题描述】:

我正在尝试创建一个将数据从一个表填充到另一个表的过程。如果存在列组合,则更新目标表中的两列。如果不存在列组合,则在目标表中创建或覆盖记录。

有人/任何人可以帮我解决提到的错误吗?我会感激你的。

这是程序。

create or replace PROCEDURE           "PRO_1_Table_2_another" AS

CURSOR C1_CUR IS
SELECT    D.D1
          ,SUBSTR(SISR.S1,1,4)
          ,SISR.S2
          ,SISR.S3
          ,SISR.S4
          ,SISR.S5
          ,SISR.S6
          ,SISR.S7
          ,SISR.S8
          ,SISR.S9
    FROM  something_in_system_record SISR
         ,Dump D
    WHERE SUBSTR(SISR.A1,1,4)=D.D1;

    TYPE C1_TA is table of C1_CUR%ROWTYPE;
    V_C1 C1_TA;

  BEGIN


   FOR i in C1_CUR LOOP

   V_C1 := C1_TA; --Error(26,12): PLS-00330: invalid use of type name or subtype name
          MERGE INTO In_something TGT
          USING
          (SELECT V_C1(i).A1 AS  A1,
                  V_C1(i).A2 AS  A2,
                  V_C1(i).A3 AS  A3,
                  V_C1(i).A4 AS  A4,
                  V_C1(i).A5 AS  A5,
                  V_C1(i).A6 AS  A6,
                  V_C1(i).A7 AS  A7,
                  V_C1(i).A8 AS  A8,
                  V_C1(i).A9 AS  A9 --Error(37,19): PL/SQL: ORA-00904: :invalid identifier &&& Error(37,24): PLS-00382: expression is of wrong type
          FROM DUAL) SRC
          ON     (SRC.A1 = TGT.A1
              AND SRC.A2 = TGT.A2
              AND SRC.A3 = TGT.A3
              AND SRC.A4 = TGT.A4
              AND SRC.A5 = TGT.A5
              AND SRC.A6 = TGT.A6
              AND SRC.A7 = TGT.A7
          )
          WHEN MATCHED THEN
            UPDATE SET TGT.A8 = SRC.A8,
                       TGT.A9 = SRC.A9
          WHEN NOT MATCHED THEN
          INSERT (TGT.A1
               ,TGT.A2
               ,TGT.A3
               ,TGT.A4
               ,TGT.A5
               ,TGT.A6
               ,TGT.A7
               ,TGT.A8
               ,TGT.A9)   
          VALUES 
              (SRC.S1
              ,SRC.S2
              ,SRC.S3
              ,SRC.S4
              ,SRC.S5
              ,SRC.S6
              ,SRC.S7
              ,SRC.S8
              ,SRC.S9);          
     END LOOP;
   COMMIT;
   EXCEPTION 
  WHEN OTHERS THEN 
  DBMS_OUTPUT.PUT_LINE(SQLCODE||' - '||SQLERRM);
END PRO_1_Table_2_another;

【问题讨论】:

  • 我已经更新了我的问题,指出错误是在哪里产生的。
  • 你好像在混合 A1 和 S1 等,它们在两个表中实际上都是一样的吗?

标签: database cursor oracle-sqldeveloper procedure


【解决方案1】:

ORA-00904: : invalid identifier 会在您错过拼写列名时出现。

就像你有一个表 Employee 有以下列。

|ID|Name|Address|

然后你写一个这样的 DML 语句,

select * from Employee where Adress like '%abcpqr%'

然后它会抛出这个异常。 ORA-00904: : invalid identifier

希望它会有所帮助。

【讨论】:

  • 我检查了所有的列。它们没有拼写错误。感谢您的帮助。
【解决方案2】:

你的C1_TA 类型是一个集合,所以

V_C1 := C1_TA;

应该是:

V_C1 := C1_TA();

...但你不需要它;您正在混合不同的光标类型。您似乎已经编写了其中的一部分,就好像您将批量收集到您的表类型中,然后使用 i 作为索引;但这里i 是一个记录类型。你根本不需要你的表类型,或者它的变量实例。

您还没有为SUBSTR(SISR.S1,1,4) 添加列别名,因此稍后引用S1 无效;并且您在几个地方混淆了 A1/S1 名称,这可能是由于手动更改真实列的名称以隐藏它们(这很好,但要始终如一)。

所以纠正所有你会得到:

create or replace PROCEDURE           "PRO_1_Table_2_another" AS

CURSOR C1_CUR IS
SELECT    D.D1
          ,SUBSTR(SISR.S1,1,4) AS S1
          ,SISR.S2
          ,SISR.S3
          ,SISR.S4
          ,SISR.S5
          ,SISR.S6
          ,SISR.S7
          ,SISR.S8
          ,SISR.S9
    FROM  something_in_system_record SISR
         ,Dump D
    WHERE SUBSTR(SISR.S1,1,4)=D.D1;

  BEGIN

   FOR i in C1_CUR LOOP

          MERGE INTO In_something TGT
          USING
          (SELECT i.S1 AS  A1,
                  i.S2 AS  A2,
                  i.S3 AS  A3,
                  i.S4 AS  A4,
                  i.S5 AS  A5,
                  i.S6 AS  A6,
                  i.S7 AS  A7,
                  i.S8 AS  A8,
                  i.S9 AS  A9
          FROM DUAL) SRC
          ON     (SRC.A1 = TGT.A1
              AND SRC.A2 = TGT.A2
              AND SRC.A3 = TGT.A3
              AND SRC.A4 = TGT.A4
              AND SRC.A5 = TGT.A5
              AND SRC.A6 = TGT.A6
              AND SRC.A7 = TGT.A7
          )
          WHEN MATCHED THEN
            UPDATE SET TGT.A8 = SRC.A8,
                       TGT.A9 = SRC.A9
          WHEN NOT MATCHED THEN
          INSERT (TGT.A1
               ,TGT.A2
               ,TGT.A3
               ,TGT.A4
               ,TGT.A5
               ,TGT.A6
               ,TGT.A7
               ,TGT.A8
               ,TGT.A9)   
          VALUES 
              (SRC.A1
              ,SRC.A2
              ,SRC.A3
              ,SRC.A4
              ,SRC.A5
              ,SRC.A6
              ,SRC.A7
              ,SRC.A8
              ,SRC.A9);          
     END LOOP;
   COMMIT;
   EXCEPTION 
  WHEN OTHERS THEN 
  DBMS_OUTPUT.PUT_LINE(SQLCODE||' - '||SQLERRM);
END "PRO_1_Table_2_another";
/

...但是您正在为光标中找到的每一行进行单独的合并,这实际上没有任何意义。你可以这样做:

MERGE INTO In_something TGT
USING (
    SELECT D.D1
          ,SUBSTR(SISR.S1,1,4) AS S1
          ,SISR.S2
          ,SISR.S3
          ,SISR.S4
          ,SISR.S5
          ,SISR.S6
          ,SISR.S7
          ,SISR.S8
          ,SISR.S9
    FROM  something_in_system_record SISR
    JOIN  Dump D
    ON    SUBSTR(SISR.S1,1,4)=D.D1
    ) SRC
ON  (
        SRC.S1 = TGT.A1
    AND SRC.S2 = TGT.A2
    AND SRC.S3 = TGT.A3
    AND SRC.S4 = TGT.A4
    AND SRC.S5 = TGT.A5
    AND SRC.S6 = TGT.A6
    AND SRC.S7 = TGT.A7
)
WHEN MATCHED THEN
  UPDATE SET TGT.A8 = SRC.S8,
             TGT.A9 = SRC.S9
WHEN NOT MATCHED THEN
INSERT (TGT.A1
     ,TGT.A2
     ,TGT.A3
     ,TGT.A4
     ,TGT.A5
     ,TGT.A6
     ,TGT.A7
     ,TGT.A8
     ,TGT.A9)   
VALUES 
    (SRC.S1
    ,SRC.S2
    ,SRC.S3
    ,SRC.S4
    ,SRC.S5
    ,SRC.S6
    ,SRC.S7
    ,SRC.S8
    ,SRC.S9);

... 应该做同样的事情;如果需要,您仍然可以将其粘贴在程序中。在过程中提交通常不是一个好主意,但您可能有正当理由这样做。

【讨论】:

  • @Alex....谢谢您,陛下!愿你上方的屋顶永不倒下,而那些聚集在它下面的人永不倒下。 - 爱尔兰谚语(在某处读过)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-12
  • 2018-11-07
  • 1970-01-01
  • 1970-01-01
  • 2013-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多