Oracle11g 如何在捕获异常后继续执行代码(pl sql)
捕获异常后,我需要继续执行代码。 但是当第一个异常出现时,我的代码正在退出,并且。 我尝试模拟一个错误,例如,当光标c1中的表不存在时,从不运行代码的第二部分,在那里它打开c2。 游标c1和c2查看中间表,中间表的名称随后在过程中处理 你能告诉我一些想法吗 提前谢谢你 问候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
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语句周围需要一个异常处理程序。