Reputation: 70
I am having the below proc that I am calling from Python , the issue is that I am not able to see the exception coming out of the block, for reproducing right now I have forced raise an exception but I am not able to see this in the Python side script
CREATE OR REPLACE FUNCTION mark_step
(
batch_id IN NUMBER
,request_id IN VARCHAR2
) RETURN NUMBER IS
BEGIN
INSERT INTO temp_log VALUES ('entered');
RAISE no_data_found;
return 0;
EXCEPTION
WHEN OTHERS THEN
INSERT INTO temp_log VALUES ('exception');
END mark_step;
The client script calling this function
l_result = cur.callfunc('mark_step', cx_Oracle.STRING,
[batch_id,request_id])
print(l_result)
Upvotes: 1
Views: 187
Reputation: 35900
I think there is no issue except missing return value
in the exception block
in your code.
The exception
which is raised by your function
is handled by the exception block
contained in the function
itself.
see the demo as follows:
Creating the table
SQL> CREATE TABLE TEMP_LOG ( 2 LOG_ VARCHAR2(50) 3 ); Table created. SQL>
Creating the function
, see inline comments:
SQL> CREATE OR REPLACE FUNCTION MARK_STEP ( 2 BATCH_ID IN NUMBER, 3 REQUEST_ID IN VARCHAR2 4 ) RETURN NUMBER IS 5 BEGIN 6 INSERT INTO TEMP_LOG VALUES ( 'entered' ); 7 RAISE NO_DATA_FOUND; -- error raised by this statement will be handeled by following exception block 8 RETURN 0; 9 EXCEPTION 10 WHEN OTHERS THEN 11 INSERT INTO TEMP_LOG VALUES ( 'exception' ); 12 RETURN -1; -- this is misssing in your code 13 END; 14 / Function created. SQL>
Calling the function:
SQL> SET SERVEROUT ON SQL> SQL> DECLARE 2 CNT NUMBER; 3 BEGIN 4 CNT := MARK_STEP(1, 'v'); 5 DBMS_OUTPUT.PUT_LINE('result := ' || CNT); 6 COMMIT; 7 END; 8 / result := -1 PL/SQL procedure successfully completed. SQL>
Checking the data in the temp_log table:
SQL> SELECT * FROM TEMP_LOG; LOG_ -------------------------------------------------- entered exception SQL>
See both the sections are executed and the result of the function
was also -1
.
Now, If you want to raise the error to the external calling program then you can remove the entire exception block
as follows:
SQL> CREATE OR REPLACE FUNCTION MARK_STEP ( 2 BATCH_ID IN NUMBER, 3 REQUEST_ID IN VARCHAR2 4 ) RETURN NUMBER IS 5 BEGIN 6 INSERT INTO TEMP_LOG VALUES ( 'entered' ); 7 8 COMMIT; -- added commit to see if it is working or not 9 RAISE NO_DATA_FOUND; -- error raised by this statement will be handeled by following exception block 10 RETURN 0; 11 --EXCEPTION 12 -- WHEN OTHERS THEN 13 -- INSERT INTO TEMP_LOG VALUES ( 'exception' ); 14 -- RETURN -1; -- this is misssing in your code 15 END; 16 / Function created. SQL>
Calling the updated function
and checking the data in the temp_log
table.
SQL> TRUNCATE TABLE TEMP_LOG; Table truncated. SQL> SET SERVEROUT ON SQL> SQL> DECLARE 2 CNT NUMBER; 3 BEGIN 4 CNT := MARK_STEP(1, 'v'); 5 DBMS_OUTPUT.PUT_LINE('result := ' || CNT); 6 COMMIT; 7 END; 8 / DECLARE * ERROR at line 1: ORA-01403: no data found ORA-06512: at "TEJASH.MARK_STEP", line 9 ORA-06512: at line 4 SQL> SELECT * FROM TEMP_LOG; LOG_ -------------------------------------------------- entered SQL>
See, the error
is thrown now and all the code above the raise exception
worked as expected.
I hope, you find this useful.
Cheers!!
Upvotes: 1
Reputation: 764
The function gracefully handles the exception and Python script does not get any visibility of the function having failed add Raise on the Exception Block
EXCEPTION
WHEN OTHERS THEN
INSERT INTO temp_log VALUES ('exception');
RAISE;
END mark_step;
On the Python side you could add try , except blocks to explicitly handle the exception in case you are not doing that already
try:
l_result = cur.callfunc('credit_ref_mig.mark_step', cx_Oracle.STRING,
[batch_id,request_id])
print(l_result)
except as e:
print(e)
Upvotes: 1