我在Oracle 11g中有一个存储过程,它将删除某些表中特定客户端的记录 . 以下脚本是其设置的示例 . 即使引发异常,它也将继续运行每个块 . 我们希望它在发生任何其他异常时停止运行,除了“-942表不存在” . 如果该表不存在,则该过程的其余部分应继续运行,所有其他过程应使其停止 . 我怎样才能做到这一点?
create or replace PROCEDURE SCHEMA.PURGE_RECORDS
(vCLIENT_ID IN VARCHAR2, pINPUTSCOPE IN VARCHAR2,
pSUCCESS_IND OUT VARCHAR2, pOUTCOME_DESC OUT VARCHAR2)
AS
VTABLE_NAME VARCHAR2(200);
vSQL VARCHAR2(10000);
BEGIN
IF pINPUTSCOPE = 'ALL' THEN
BEGIN
VTABLE_NAME := 'TABLE NAME';
vSQL := '
DELETE FROM TABLENAME T WHERE EXISTS (SELECT 1 FROM TABLE2 TSK WHERE CLIENT = '''|| vCLIENT_ID ||''' AND ASK_ID = T.ASK_ID) ';
EXECUTE IMMEDIATE vSQL;
DBMS_OUTPUT.PUT_LINE ( VTABLE_NAME || ' Scope set: ' || pINPUTSCOPE || ' ' || '(' || TO_CHAR(SQL%ROWCOUNT) || ' ROWS DELETED)' || chr(10));
EXCEPTION WHEN OTHERS THEN NULL; DBMS_OUTPUT.PUT_LINE('ERROR : ' || VTABLE_NAME || ' ' || SQLERRM);
END;
BEGIN
VTABLE_NAME := 'TABLE NAME';
vSQL := '
DELETE FROM TABLENAME3 T WHERE EXISTS (SELECT 1 FROM TABLE3 TSK WHERE CLIENT = '''|| vCLIENT_ID ||''' AND ASK_ID = T.ASK_ID) ';
EXECUTE IMMEDIATE vSQL;
DBMS_OUTPUT.PUT_LINE ( VTABLE_NAME || ' Scope set: ' || pINPUTSCOPE || ' ' || '(' || TO_CHAR(SQL%ROWCOUNT) || ' ROWS DELETED)' || chr(10));
EXCEPTION WHEN OTHERS THEN NULL; DBMS_OUTPUT.PUT_LINE('ERROR : ' || VTABLE_NAME || ' ' || SQLERRM);
END;
BEGIN
VTABLE_NAME := 'TABLE NAME';
vSQL := '
DELETE FROM TABLENAME4 T WHERE EXISTS (SELECT 1 FROM TABLE4 TSK WHERE CLIENT = '''|| vCLIENT_ID ||''' AND ASK_ID = T.ASK_ID) ';
EXECUTE IMMEDIATE vSQL;
DBMS_OUTPUT.PUT_LINE ( VTABLE_NAME || ' Scope set: ' || pINPUTSCOPE || ' ' || '(' || TO_CHAR(SQL%ROWCOUNT) || ' ROWS DELETED)' || chr(10));
EXCEPTION WHEN OTHERS THEN NULL; DBMS_OUTPUT.PUT_LINE('ERROR : ' || VTABLE_NAME || ' ' || SQLERRM);
END;
BEGIN
VTABLE_NAME := 'TABLE NAME';
vSQL := '
DELETE FROM TABLENAME5 T WHERE EXISTS (SELECT 1 FROM TABLE5 TSK WHERE CLIENT = '''|| vCLIENT_ID ||''' AND ASK_ID = T.ASK_ID) ';
EXECUTE IMMEDIATE vSQL;
DBMS_OUTPUT.PUT_LINE ( VTABLE_NAME || ' Scope set: ' || pINPUTSCOPE || ' ' || '(' || TO_CHAR(SQL%ROWCOUNT) || ' ROWS DELETED)' || chr(10));
EXCEPTION WHEN OTHERS THEN NULL; DBMS_OUTPUT.PUT_LINE('ERROR : ' || VTABLE_NAME || ' ' || SQLERRM);
END;
END IF;
END;
1 回答
您可以显式捕获ORA-00942错误,报告您想要的,然后忽略它;然后使用RAISE处理所有其他异常 - 这会将异常传播到下一个块,在这种情况下导致过程终止 - 或者根本不捕获它们 .
ORA-00942不是the predefined exceptions之一,因此您需要定义一个异常名称并使用the PRAGMA EXCEPTION_INIT clause将异常关联到the internally defined exception number:
并在每个子块中重复异常catch . 您的
OTHERS
处理程序仍将捕获任何其他异常 . 捕捉和挤压OTHERS
通常是一个坏主意,最好将其移除并让异常自然传播;即使你__49185_重新丢失原始问题的行号 . 所以你真的需要这样做: