在存储过程中遇到符号“EXCEPTION”错误

时间:2017-10-25 12:36:12

标签: sql oracle plsql oracle12c pls-00103

我正在编写Oracle Database 12c企业版12.1.0.2.0版 - 64位生产中的过程。

我在LOOP中有一个异常,因为如果抛出异常,我不希望该过程退出LOOP。

create or replace procedure PARSE_REGISTER_MESSAGE
  IS

        HOTELS_TO_PROCESS number := 5000;     

        cursor unparsed_messages is

         SELECT REGISTER_psd_id, message

         FROM
            ( SELECT REGISTER_psd_id, message
              FROM cc_owner.REGISTER_psd
              WHERE parsed != 1
                    OR parsed IS NULL
              ORDER BY CREATION_DATE DESC)

         WHERE rownum < HOTELS_TO_PROCESS;

    BEGIN

     FOR psd_rec in unparsed_messages
     LOOP

p_msg.parse_msg (psd_rec.REGISTER_psd_id, null, psd_rec.message);

         EXCEPTION

        WHEN OTHERS
        THEN 
        DECLARE
            l_code   INTEGER := SQLCODE;
        BEGIN

            of_owner.p_db_trc.add_error
                 ( 'PARSE_REGISTER_MESSAGE','', 
                    l_code, 
                    sys.DBMS_UTILITY.format_error_stack, 
                    sys.DBMS_UTILITY.format_error_backtrace, 
                    sys.DBMS_UTILITY.format_call_stack ); 

        END;

    END LOOP;

END;

但由于此错误,我无法编译包:

  

错误(25,10):PLS-00103:遇到以下其中一项时遇到符号“EXCEPTION”:
  (开始情况声明结束退出goto if if loop mod null pragma raise return select update with&lt;&lt; continue close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe purge

我也试过了:

create or replace procedure PARSE_REGISTER_MESSAGE
  IS

        HOTELS_TO_PROCESS number := 5000;     

        cursor unparsed_messages is

         SELECT REGISTER_psd_id, message

         FROM
            ( SELECT REGISTER_psd_id, message
              FROM cc_owner.REGISTER_psd
              WHERE parsed != 1
                    OR parsed IS NULL
              ORDER BY CREATION_DATE DESC)

         WHERE rownum < HOTELS_TO_PROCESS;

         psd_rec unparsed_messages%ROWTYPE;

    BEGIN

     FOR psd_rec in unparsed_messages
     LOOP
        BEGIN

          p_msg.parse_msg (psd_rec.REGISTER_psd_id, null, psd_rec.message);

         EXCEPTION

        WHEN OTHERS
        THEN 
        DECLARE
            l_code   INTEGER := SQLCODE;
        BEGIN

            of_owner.p_db_trc.add_error
                 ( 'PARSE_REGISTER_MESSAGE','', 
                    l_code, 
                    sys.DBMS_UTILITY.format_error_stack, 
                    sys.DBMS_UTILITY.format_error_backtrace, 
                    sys.DBMS_UTILITY.format_call_stack ); 

        END;

    END LOOP;

END;

但后来我收到了这个错误:

Error(48,4): PLS-00103: Encountered the symbol ";" when expecting one of the following:     loop 

2 个答案:

答案 0 :(得分:1)

尝试使用Begin after循环关键字,因为缺少一个BEGIN

for unparsed_messages中的psd_rec      环 开始 p_msg.parse_msg(psd_rec.REGISTER_psd_id,null,psd_rec.message);

     EXCEPTION

    WHEN OTHERS
    THEN 
    DECLARE
        l_code   INTEGER := SQLCODE;
    BEGIN

        of_owner.p_db_trc.add_error
             ( 'PARSE_REGISTER_MESSAGE','', 
                l_code, 
                sys.DBMS_UTILITY.format_error_stack, 
                sys.DBMS_UTILITY.format_error_backtrace, 
                sys.DBMS_UTILITY.format_call_stack ); 

    END;

答案 1 :(得分:0)

PLSQL block / procedure的语法是:

DECLARE
 -- Here you declare all the varaible used in block
BEGIN
 -- Here you write the body of the Block
EXCEPTION
 -- Here you write the exceptions which you want to handle.
END;

现在,当我查看您的代码时,您已在Exception内部编写了FOR LOOP块,只有在您使用上述语法时才会有效。在您的情况下,Exception块的范围未由Oracle标识,因此会引发错误。

 FOR psd_rec IN unparsed_messages
   LOOP
      p_msg.parse_msg (psd_rec.REGISTER_psd_id, NULL, psd_rec.MESSAGE);         

      EXCEPTION  --<-- Wrong way of using Excepton block. Scope of this Exception block is not resolved
        WHEN OTHERS
        THEN
        DECLARE
            l_code   INTEGER := SQLCODE;
        BEGIN
            of_owner.p_db_trc.add_error
                 ( 'PARSE_REGISTER_MESSAGE','',
                    l_code,
                    sys.DBMS_UTILITY.format_error_stack,
                    sys.DBMS_UTILITY.format_error_backtrace,
                    sys.DBMS_UTILITY.format_call_stack );

        END;

您必须修改以下代码,以便在for循环中包含Exception块;

  CREATE OR REPLACE PROCEDURE PARSE_REGISTER_MESSAGE
    IS
       HOTELS_TO_PROCESS   NUMBER := 5000;
       l_code              INTEGER := SQLCODE;

       CURSOR unparsed_messages
       IS
          SELECT REGISTER_psd_id, MESSAGE
            FROM (  SELECT REGISTER_psd_id, MESSAGE
                      FROM cc_owner.REGISTER_psd
                     WHERE parsed != 1 OR parsed IS NULL
                  ORDER BY CREATION_DATE DESC)
           WHERE ROWNUM < HOTELS_TO_PROCESS;
    BEGIN
       FOR psd_rec IN unparsed_messages
       LOOP
          BEGIN
             p_msg.parse_msg (psd_rec.REGISTER_psd_id, NULL, psd_rec.MESSAGE);
          EXCEPTION
             WHEN OTHERS
             THEN
                of_owner.p_db_trc.add_error (
                   'PARSE_REGISTER_MESSAGE',
                   '',
                   l_code,
                   sys.DBMS_UTILITY.format_error_stack,
                   sys.DBMS_UTILITY.format_error_backtrace,
                   sys.DBMS_UTILITY.format_call_stack);
          END;
       END LOOP;
 EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.put_line (SQLERRM);    
END;

您第二次尝试缺少END语句,这就是您收到错误的原因。见下文:

CREATE OR REPLACE PROCEDURE PARSE_REGISTER_MESSAGE
IS
   HOTELS_TO_PROCESS   NUMBER := 5000;
   l_code              INTEGER := SQLCODE;

   CURSOR unparsed_messages
   IS
      SELECT REGISTER_psd_id, MESSAGE
        FROM (  SELECT REGISTER_psd_id, MESSAGE
                  FROM cc_owner.REGISTER_psd
                 WHERE parsed != 1 OR parsed IS NULL
              ORDER BY CREATION_DATE DESC)
       WHERE ROWNUM < HOTELS_TO_PROCESS;

   psd_rec             unparsed_messages%ROWTYPE;
BEGIN
   FOR psd_rec IN unparsed_messages
   LOOP
      BEGIN
         p_msg.parse_msg (psd_rec.REGISTER_psd_id, NULL, psd_rec.MESSAGE);
      EXCEPTION
         WHEN OTHERS
         THEN
            BEGIN
               of_owner.p_db_trc.add_error (
                  'PARSE_REGISTER_MESSAGE',
                  '',
                  l_code,
                  sys.DBMS_UTILITY.format_error_stack,
                  sys.DBMS_UTILITY.format_error_backtrace,
                  sys.DBMS_UTILITY.format_call_stack);
            END;
      END;
   END LOOP;
END;