[英]How to retrieve output parameter from stored procedure in oracle
我有下面的存储过程。 工作正常。 但是我想测试它的错误情况。 即使出现错误,该过程也会成功执行,而不会显示错误消息。 当我启用set serveroutput时,它显示错误消息。 但是我想捕获错误消息。
create or replace PROCEDURE COMP_JSON (
OUT_MESSAGE OUT VARCHAR2,
PNI_ID IN NUMBER
)
AS
CURSOR C1 IS SELECT 1 AS ID,TYPE_ID, COMP, TYPE, PREV_AMOUNT, CURR_AMOUNT FROM V_COMP_COST;
SECID VARCHAR2(100);
K NUMBER:= 0;
L NUMBER:= 1000;--Commit Interval
LRETVALUE VARCHAR2(200):='0';
V_TYPE_ID JSON_DATA.TYPE_ID%TYPE;
V_COMP JSON_DATA.COMP%TYPE;
V_TYPE JSON_DATA.TYPE%TYPE;
BEGIN
APEX_JSON.INITIALIZE_CLOB_OUTPUT;
/* Cost Comparison */
IF NVL(PNI_ID, 1) = 1
THEN
K := 0;
BEGIN
FOR I IN C1
LOOP
V_TYPE_ID := I.TYPE_ID;
V_COMP := I.COMP;
V_TYPE := I.TYPE;
APEX_JSON.OPEN_OBJECT;
APEX_JSON.WRITE('prevAmt',I.PREV_AMOUNT);
APEX_JSON.WRITE('currAmt',I.CURR_AMOUNT);
APEX_JSON.CLOSE_OBJECT;
INSERT INTO JSON_DATA
VALUES (I.ID,I.TYPE_ID,I.COMP,I.TYPE,APEX_JSON.GET_CLOB_OUTPUT);
/* Commit Interval */
K := K+1;
IF MOD(K,L) = 0
THEN
COMMIT;
END IF;
APEX_JSON.FREE_OUTPUT;
IF K > 5
THEN
RAISE_APPLICATION_ERROR(-20000, NULL);
END IF;
END LOOP;
EXCEPTION
WHEN OTHERS
THEN LRETVALUE := '-1,k:Problem in loading Data -' || SQLERRM || ' AT: [' || V_TYPE_ID || '] [' || V_COMP || '] [' || V_TYPE || ']';
END;
COMMIT;
IF LRETVALUE <> '0'
THEN
OUT_MESSAGE := LRETVALUE;
RETURN;
END IF;
END IF;
EXCEPTION
WHEN OTHERS
THEN DBMS_OUTPUT.PUT_LINE('ERROR MESSAGE' || SQLERRM);
END COMP_JSON;
您正在使用嵌套块引发异常,但是它将继续处理。 出站变量“ OUT_MESSAGE”应捕获该值。 是吗? 如果是这样,您可以看到它的含义:
SQL> VAR ERR_MSG VARCHAR2;
SQL> EXEC COMP_JSON(:ERR_MSG, 5); --whatever you use for PNI_ID....
PL/SQL procedure successfully completed.
SQL> PRINT ERR_MSG;
如果您的程序从不抛出错误,则将永远不会设置OUT_MESSAGE,因此在程序完成时它将为null。
如果您希望在“嵌套块”引发错误的情况下从程序中引发错误,则需要重新引发异常,以便外部异常可以捕获该异常:
IF K > 5
THEN
RAISE_APPLICATION_ERROR(-20000, NULL);
END IF;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
LRETVALUE := '-1,k:Problem in loading Data -' || SQLERRM || ' AT: [' || V_TYPE_`ID || '] [' || V_COMP || '] [' || V_TYPE || ']';
RAISE_APPLICATION_ERROR(-20000, LRETVALUE );
END;
如果需要调用方引发异常,则需要过程将其传播到外部。 例如:
SQL> create or replace procedure raiseException(p in number) is
2 n number;
3 begin
4 n := p/0;
5 exception
6 when others then
7 dbms_output.put_line('Error message: ' || sqlerrm);
8 raise;
9 end;
10 /
Procedure created.
SQL> create or replace procedure procedureCall is
2 begin
3 raiseException(10);
4 end;
5 /
Procedure created.
第一个过程将打印一条消息并引发异常。 这样,我们在输出中会显示错误消息和一个异常:
SQL> exec procedureCall
Error message: ORA-01476: divisor is equal to zero
BEGIN procedureCall; END;
*
ERROR at line 1:
ORA-01476: divisor is equal to zero
ORA-06512: at "ALEK.RAISEEXCEPTION", line 8
ORA-06512: at "ALEK.PROCEDURECALL", line 3
ORA-06512: at line 1
如果删除RAISE
,则异常将被处理且不会传播,因此不会出现错误:
SQL> create or replace procedure raiseException(p in number) is
2 n number;
3 begin
4 n := p/0;
5 exception
6 when others then
7 dbms_output.put_line('Error message: ' || sqlerrm);
8 end;
9 /
Procedure created.
SQL> exec procedureCall
Error message: ORA-01476: divisor is equal to zero
PL/SQL procedure successfully completed.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.