Oracle11g 如何在捕获异常后继续执行代码(pl sql)

Oracle11g 如何在捕获异常后继续执行代码(pl sql),oracle11g,exception-handling,Oracle11g,Exception Handling,捕获异常后,我需要继续执行代码。 但是当第一个异常出现时,我的代码正在退出,并且。 我尝试模拟一个错误,例如,当光标c1中的表不存在时,从不运行代码的第二部分,在那里它打开c2。 游标c1和c2查看中间表,中间表的名称随后在过程中处理 你能告诉我一些想法吗 提前谢谢你 问候 CREATE OR REPLACE PROCEDURE ISRREP.isr_retention IS v_count NUMBER ;--:= 50; v_commit

捕获异常后,我需要继续执行代码。 但是当第一个异常出现时,我的代码正在退出,并且。 我尝试模拟一个错误,例如,当光标c1中的表不存在时,从不运行代码的第二部分,在那里它打开c2。 游标c1和c2查看中间表,中间表的名称随后在过程中处理

你能告诉我一些想法吗

提前谢谢你

问候

CREATE OR REPLACE PROCEDURE ISRREP.isr_retention
IS


   v_count           NUMBER         ;--:= 50;
   v_commit          NUMBER         := 50;
   str_min           VARCHAR2 (100);
   str_del_day       VARCHAR2 (150);
   str_del_month     VARCHAR2 (150);
   str_lastdate      VARCHAR2 (150);
   v_lastdate        DATE;
   v_lastdate_fin    DATE;
   str_min_fin       VARCHAR2 (100);
   v_hay_registros   NUMBER         ; --:= 1;
   errno             NUMBER;
   errmsg            VARCHAR2 (255);
   str_error         VARCHAR2 (300);
   str_upd_err       VARCHAR2 (300);
   v_table1          VARCHAR2 (50);
   v_table2          VARCHAR2 (50);
   v_table3          VARCHAR2 (50);
   v_table4          VARCHAR2 (50);
   v_table5          VARCHAR2 (50);

   /* armo cursor */
   CURSOR c1
   IS
      SELECT   ID, activeflag, errormessage, tablename, retention,
               retentionunit, lastdate
          FROM isrfrequency_sacme
         WHERE activeflag = 'ACTIVE'
         AND retentionunit = 'Month'
      ORDER BY tablename;

       CURSOR c2
   IS
      SELECT   ID, activeflag, errormessage, tablename, retention,
               retentionunit, lastdate
          FROM isrfrequency_sacme
         WHERE activeflag = 'ACTIVE'
         AND retentionunit = 'Day'
      ORDER BY tablename;  

   r1                c1%ROWTYPE;
   r2                c2%ROWTYPE;

    BEGIN


           OPEN c1;


               LOOP
                  FETCH c1
                   INTO r1;

                  EXIT WHEN c1%NOTFOUND;



                  str_min := 'select min(utctime) from ' || r1.tablename;          --Obtengo fecha y hora mas antigua

                  EXECUTE IMMEDIATE str_min INTO v_lastdate;


                      --Tablas con retencionunit Month

                      BEGIN

                       r1.retentionunit := 'Month';

                                 str_del_month := 'delete '|| r1.tablename    
                                    || ' where UTCTIME < ADD_MONTHS(sysdate,-' --|| ' where UTCTIME < trunc(ADD_MONTHS(sysdate,-'
                                    || r1.RETENTION
                                    || ')';                                    --Delete de registros que exceden la retencion


                                 EXECUTE IMMEDIATE str_del_month;

                                 v_table1 := r1.tablename;

                                 v_hay_registros := SQL%ROWCOUNT;

                                     IF v_hay_registros != 0
                                     THEN
                                        COMMIT;

                                     END IF;

                                 str_min_fin := 'select min(utctime) from ' || r1.tablename;                        --Obtengo nuevamente fecha y hora mas antigua

                                 EXECUTE IMMEDIATE str_min_fin INTO v_lastdate_fin;

                                 str_lastdate :=
                                       'update ISRFREQUENCY_SACME set LASTDATE = TO_DATE('''
                                    || v_lastdate_fin
                                    || ''',''DD/MM/YYYY HH24:MI:SS'') where tablename = '''
                                    || r1.tablename
                                    || '''';                                                                       --Update en tabla ISRFREQUENCY_SACME con el ultimo valor leido

                                 --DBMS_OUTPUT.put_line (str_lastdate);

                                 EXECUTE IMMEDIATE str_lastdate;


                                --
                                -- EXEPCIONES PARCIALES
                                --
                          EXCEPTION
                          WHEN OTHERS
                          THEN
                                   errno := SQLCODE;
                                   errmsg := SQLERRM;

                                test_debug.p_test_debug_out ('ISR_RETENTION', errmsg, 'NO');

                                update isrfrequency_sacme set activeflag = 'ERROR', errormessage = errmsg  where tablename = r1.tablename;
                                commit;

                                DBMS_OUTPUT.put_line ('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++');
                                DBMS_OUTPUT.put_line (   'ERROR: '|| errmsg || '. ISRFREQUENCY_SACME.MESSAGGE');
                                DBMS_OUTPUT.put_line ('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++');

                                DBMS_OUTPUT.PUT_LINE('Se ha producido una excepción.');
                                DBMS_OUTPUT.PUT_LINE('Error code: ' || SQLCODE);
                                DBMS_OUTPUT.PUT_LINE('Error message: ' || SQLERRM);


                          END;                               

               END LOOP;    

            CLOSE c1;       



                              --Tablas con retencionunit Day      

            OPEN c2;


               LOOP
                  FETCH c2
                   INTO r2;

                  EXIT WHEN c2%NOTFOUND;


                      BEGIN

                              r1.retentionunit := 'Day';

                                 str_del_day :=
                                       'delete '
                                    || r2.tablename
                                    || ' where UTCTIME < trunc(sysdate-'
                                    || r2.RETENTION
                                    || ')';                                                              --Delete de registros que exceden la retencion




                                 EXECUTE IMMEDIATE str_del_day;


                                 v_table2 := r2.tablename;

                                 v_hay_registros := SQL%ROWCOUNT;
                                 --v_hay_registros := v_count;

                                     IF v_hay_registros != 0
                                     --IF v_count != 0

                                     THEN
                                        COMMIT;


                                     ELSE

                                     END IF;

                                 str_min_fin := 'select min(utctime) from ' || r2.tablename;                                   --Obtengo nuevamente fecha y hora mas antigua

                                 EXECUTE IMMEDIATE str_min_fin INTO v_lastdate_fin;


                                 str_lastdate :=
                                       'update ISRFREQUENCY_SACME set LASTDATE = TO_DATE('''
                                    || v_lastdate_fin
                                    || ''',''DD/MM/YYYY HH24:MI:SS'') where tablename = '''
                                    || r2.tablename
                                    || '''';                                                           --Update en tabla ISRFREQUENCY_SACME con el ultimo valor UTCTIME, luego del delete

                                 --DBMS_OUTPUT.put_line (str_lastdate);

                                 EXECUTE IMMEDIATE str_lastdate;


                              --
                              -- EXEPCIONES PARCIALES
                              --
                                EXCEPTION
                                WHEN OTHERS
                                THEN
                                        errno := SQLCODE;
                                        errmsg := SQLERRM;

                                test_debug.p_test_debug_out ('ISR_RETENTION', errmsg, 'NO');

                                update isrfrequency_sacme set activeflag = 'ERROR', errormessage = errmsg  where tablename = r2.tablename;
                                commit;

                                DBMS_OUTPUT.put_line ('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++');
                                DBMS_OUTPUT.put_line (   'ERROR: '|| errmsg || '. ISRFREQUENCY_SACME.MESSAGGE');
                                DBMS_OUTPUT.put_line ('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++');

                                DBMS_OUTPUT.PUT_LINE('Se ha producido una excepción.');
                                DBMS_OUTPUT.PUT_LINE('Error code: ' || SQLCODE);
                                DBMS_OUTPUT.PUT_LINE('Error message: ' || SQLERRM);

                                --NULL;

                                END;


               END LOOP;

       CLOSE c2;


    --
    -- EXEPCIONES FINALES
    --
    EXCEPTION
       WHEN OTHERS
       THEN
          errno := SQLCODE;
          errmsg := SQLERRM;

          test_debug.p_test_debug_out ('ISR_RETENTION', errmsg, 'NO');

          update isrfrequency_sacme set activeflag = 'ERROR', errormessage = errmsg  where tablename = r1.tablename;
          commit;

          DBMS_OUTPUT.put_line ('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++');
          DBMS_OUTPUT.put_line (   'ERROR: '|| errmsg || '. ISRFREQUENCY_SACME.MESSAGGE');
          DBMS_OUTPUT.put_line ('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++');

          DBMS_OUTPUT.PUT_LINE('Se ha producido una excepción.');
          DBMS_OUTPUT.PUT_LINE('Error code: ' || SQLCODE);
          DBMS_OUTPUT.PUT_LINE('Error message: ' || SQLERRM);

    END;   

/

你犯了什么错误?您的描述不是特别清楚,但听起来好像是在创建编译错误。如果过程未能成功编译,则无法执行任何部分。任何异常处理程序都无法捕获静态SQL中的编译错误。不是编译错误。捕获的错误是:{ISR_RETENTION:ORA-00942:la tabla o vista no existe},此时c1未找到表名。如果ORA-00942错误通常是编译错误,则该过程将被编译。如果这是一个运行时错误,那么它一定来自正在执行的许多动态SQL语句之一。哪个特定的动态SQL语句失败?c1正在搜索表列表。其中一个不存在,因为我暂时给她重命名。然后错误是“ORA-00942”,但我需要代码继续执行以下内容,即c2。这是可能的还是我必须尝试模拟其他类型的错误?各种动态SQL语句中哪一种失败了?在动态SQL语句周围需要一个异常处理程序。