2017-10-25 11 views
0

Oracle 데이터베이스 12c Enterprise Edition 릴리스 12.1.0.2.0 - 64 비트 프로덕션에서 프로 시저를 프로그래밍하고 있습니다.저장 프로 시저에서 "EXCEPTION"오류가 발생했습니다.

예외가 발생하는 경우 프로 시저가 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; 

하지만이 오류로 인해 패키지 컴파일 할 수 없습니다 :

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(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

나는 또한 시도

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

답변

0

PLSQLblock/procedure의 구문은 다음과 같습니다 위의 사용하는 경우에만 작동합니다 내가 코드를 볼 때 지금, 당신은 FOR LOOP 내부 Exception 블록을 작성했습니다

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 블록의 범위는 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 블록을 포함하도록 다음과 같이 코드를 수정해야합니다

;

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; 
1

Begin after 루프 키워드를 사용하여 BEGIN을 (를) 사용해보십시오. unparsed_messages에 psd_rec FOR

을 놓치기 LOOP p_msg.parse_msg (psd_rec.REGISTER_psd_id, NULL, psd_rec.message)를 BEGIN;

 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;