0

我正在对 Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production 中的程序进行编程。

我在 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”:(
begin case declare end exit for goto if loop mod null pragma raise return select update while with << 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 
4

2 回答 2

1

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

FOR psd_rec in unparsed_messages 循环开始 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;
于 2017-10-25T12:44:38.747 回答
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;

您必须如下修改您的代码以将Exception块包含在 for 循环中;

  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;
于 2017-10-26T07:12:17.697 回答