oracle过程异常编译错误

Posted

技术标签:

【中文标题】oracle过程异常编译错误【英文标题】:Oracle procedure exception compile error 【发布时间】:2014-05-17 10:36:19 【问题描述】:

我想编写删除记录的程序,我传递给程序表名称和ID。

CREATE OR REPLACE PROCEDURE TRYNIMAS(
ID NUMBER,
LENTELE VARCHAR2,
KLAIDA OUT VARCHAR2
)
IS
INUSE EXCEPTION;
PRAGMA EXCEPTION_INIT (INUSE,-02292 );
BEGIN
IF LENTELE  = 'table1' THEN
DELETE FROM KATEGORIJOS WHERE KAT_ID = ID;

ELSE IF LENTELE  = 'table2' THEN
DELETE FROM KATEGORIJOS WHERE PRT_ID = ID;

ELSE IF LENTELE  = 'table3' THEN
DELETE FROM KATEGORIJOS WHERE TK_ID = ID;

ELSE IF LENTELE  = 'table4' THEN
DELETE FROM KATEGORIJOS WHERE PR_ID = ID;

ELSE IF LENTELE  = 'table5' THEN
DELETE FROM KATEGORIJOS WHERE PIRK_ID = ID;

ELSE IF LENTELE  = 'table6' THEN
DELETE FROM KATEGORIJOS WHERE TK_ID = ID;

ELSE 
KLAIDA:= 'TABLE OR RECORD NOT EXIST';

END IF;

EXCEPTION 
WHEN INUSE THEN KLAIDA:= 'Record is in usera and can not be deleted';
WHEN OTHERS THEN KLAIDA:= 'Error!';
END;

我收到编译错误:

错误(33,1):PLS-00103:在预期以下情况之一时遇到符号“EXCEPTION”:( begin case declare end exit for goto if loop mod null pragma raise return select update while with

错误(36,4):PLS-00103:在预期以下情况之一时遇到符号“文件结尾”:end not pragma final instanceiable order overriding static member constructor map

【问题讨论】:

【参考方案1】:

我建议用 CASE 语句替换 IF...ELSIF...ELSIF:

CREATE OR REPLACE PROCEDURE TRYNIMAS
  (ID      IN  NUMBER,
   LENTELE IN  VARCHAR2,
   KLAIDA  OUT VARCHAR2)
IS
  INUSE EXCEPTION;
  PRAGMA EXCEPTION_INIT (INUSE,-02292 );
BEGIN
  CASE LENTELE
    WHEN table1 THEN
      DELETE FROM KATEGORIJOS WHERE KAT_ID = ID;
    WHEN table2 THEN
      DELETE FROM KATEGORIJOS WHERE PRT_ID = ID;
    WHEN table3 THEN
      DELETE FROM KATEGORIJOS WHERE TK_ID = ID;
    WHEN table4 THEN
      DELETE FROM KATEGORIJOS WHERE PR_ID = ID;
    WHEN table5 THEN
      DELETE FROM KATEGORIJOS WHERE PIRK_ID = ID;
    WHEN LENTELE  = table6 THEN
      DELETE FROM KATEGORIJOS WHERE TK_ID = ID;
    ELSE 
      KLAIDA:= 'TABLE OR RECORD NOT EXIST';
  END CASE;
EXCEPTION 
  WHEN INUSE THEN
    KLAIDA:= 'Record is in usera and can not be deleted';
  WHEN OTHERS THEN
    KLAIDA:= 'Error!';
END TRYNIMAS;

我仍然不知道这是否会编译,因为我不知道 table1、table2 等被声明为什么 - 它们是字符串还是数据库中的表? (如果它们是字符串,这可能会编译。如果它们是数据库中的表,您将不得不做一些不同的事情。

分享和享受。

【讨论】:

【参考方案2】:

将您所有的ELSE IFs 替换为ELSIF

我已格式化您的程序以显示 Oracle 正在解释它:

CREATE OR REPLACE PROCEDURE TRYNIMAS(
  ID NUMBER,
  LENTELE VARCHAR2,
  KLAIDA OUT VARCHAR2
)
IS
  INUSE EXCEPTION;
  PRAGMA EXCEPTION_INIT (INUSE,-02292 );
BEGIN
  IF LENTELE  = table1 THEN
    DELETE FROM KATEGORIJOS WHERE KAT_ID = ID;

  ELSE
    IF LENTELE  = table2 THEN
      DELETE FROM KATEGORIJOS WHERE PRT_ID = ID;

    ELSE
      IF LENTELE  = table3 THEN
        DELETE FROM KATEGORIJOS WHERE TK_ID = ID;

      ELSE
        IF LENTELE  = table4 THEN
          DELETE FROM KATEGORIJOS WHERE PR_ID = ID;

        ELSE 
          IF LENTELE  = table5 THEN
            DELETE FROM KATEGORIJOS WHERE PIRK_ID = ID;

          ELSE
            IF LENTELE  = table6 THEN
              DELETE FROM KATEGORIJOS WHERE TK_ID = ID;

            ELSE 
              KLAIDA:= 'TABLE OR RECORD NOT EXIST';

            END IF;

            EXCEPTION 
              WHEN INUSE THEN KLAIDA:= 'Record is in usera and can not be deleted';
              WHEN OTHERS THEN KLAIDA:= 'Error!';
            END;

在这种情况下,您可以看到它在抱怨,因为它在多个 IF 语句中时得到了 EXCEPTION

您当然可以通过添加所有缺少的END IFs 来修复您的过程,但使用ELSIF 而不是ELSE IF 更简单。

【讨论】:

你尝试了什么?将ELSE IF 替换为ELSIF,还是添加缺少的END IFs?我用ELSIFs 替换了所有ELSE IFs,并为我编译了你的程序。【参考方案3】:

一旦你选择的语法工作 - 你仍然需要

    添加显式提交 - 如果调用进程未处理提交。

    解决 WHEN OTHERS 的不当使用问题

WHEN OTHERS THEN KLAIDA:= 'Error!';

这不应该用于处理预期的数据错误。它用于系统错误和意外数据问题,应该会导致您的程序失败。

WHEN OTHERS 
THEN 
  ROLLBACK;
  KLAIDA:= 'Error!';
  DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_STACK);
  DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
  RAISE;
END;

【讨论】:

以上是关于oracle过程异常编译错误的主要内容,如果未能解决你的问题,请参考以下文章

oracle存储过程提示编译完成但存在错误,如何查看错误

编译过程时出现oracle错误

Oracle 存储过程编译错误

Oracle 过程的编译错误

警告:已编译但在 oracle 中存在编译错误

限制 Oracle 创建编译错误程序