简体   繁体   中英

Encountered the symbol “EXCEPTION” error in stored procedure

I am programming a procedure in an Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production.

I have an exception inside a LOOP because I don't want the procedure to exit the LOOP if an exception is thrown.

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;

But I can't compile the package due this error:

Error(25,10): PLS-00103: Encountered the symbol "EXCEPTION" when expecting one of the following:
( 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

I Also tried:

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;

But then I got this error:

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

Try using Begin after loop keyword as one BEGIN is missing

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;

The syntax for a PLSQL block / procedure is :

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;

Now when i look at your code, you have written Exception block inside the FOR LOOP , which will work only if you use the above syntax. In you case the scope of Exception block is not identified by Oracle and hence it throws error.

 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;

You must modify your code as below to include the Exception block in for loop;

  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;

You second try has missing END statement and thats why you were getting error. See below:

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM