[英]How to retrieve output parameter from stored procedure in oracle
I have below stored procedure. 我有下面的存储过程。 It works fine.
工作正常。 But I wanted to test it for error scenarios.
但是我想测试它的错误情况。 Even when there is an error, the procedure executes successfully without showing the error message.
即使出现错误,该过程也会成功执行,而不会显示错误消息。 When I enable the set serveroutput on, it shows the error message.
当我启用set serveroutput时,它显示错误消息。 But I want to capture the error message.
但是我想捕获错误消息。
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;
You're using a nested block to throw your exception, but it will continue processing. 您正在使用嵌套块引发异常,但是它将继续处理。 The outbound variable "OUT_MESSAGE" should capture that value.
出站变量“ OUT_MESSAGE”应捕获该值。 Is it?
是吗? if so, you can see what it is with this:
如果是这样,您可以看到它的含义:
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;
If your program never throws an error, then OUT_MESSAGE will never be set, thus it will be null upon completion of the program. 如果您的程序从不抛出错误,则将永远不会设置OUT_MESSAGE,因此在程序完成时它将为null。
If you are looking to throw an error from your program if your "nested block" throws an error, then you need to re-raise the exception so that the outer exception catches it: 如果您希望在“嵌套块”引发错误的情况下从程序中引发错误,则需要重新引发异常,以便外部异常可以捕获该异常:
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;
If you need the caller to raise an exception, you need that your procedure propagates it to the external. 如果需要调用方引发异常,则需要过程将其传播到外部。 For example:
例如:
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.
The first procedure will print a message and raise an exception; 第一个过程将打印一条消息并引发异常。 in this way, we have the error message in output and an exception:
这样,我们在输出中会显示错误消息和一个异常:
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
If you remove the RAISE
, the exception will be handled and not propagated, thus giving no error: 如果删除
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.