我正在从 Python 执行 PL/SQL 过程,该过程返回用户定义的异常。但是,我没有收到 PL/SQL 包中定义的异常代码和消息。如何获取用户自定义的异常代码和消息?
SQL代码:
PROCESSING_ERROR EXCEPTION;
PROCEDURE my_procedure(
exception_code OUT NUMBER,
exception_message OUT VARCHAR2)
IS
row_count number;
BEGIN
--Initialize the return parms.
exception_code := 0;
exception_message := NULL;
select count(*) from my_table into row_count;
if row_count > 0 then
raise processing_error;
end if;
EXCEPTION
-- An business rule or schema rule error was detected.
WHEN PROCESSING_ERROR THEN
dbms_output.put_line('Business rule or schema rule erorrs.');
exception_code := -20001;
exception_message := 'Data violated business logic';
-- Local error - capture the Oracle codes and pass back to the caller.
WHEN OTHERS THEN
exception_code := SQLCODE;
exception_message := 'my_procedure: ' || SUBSTR(SQLERRM, 1, 255);
END my_procedure;
Python代码:
import oracledb
exception_code = cursor.var(int)
exception_message = cursor.var(str)
try:
cursor.callproc('my_package.my_procedure', [exception_code, exception_message])
except oracledb.Error as e:
err, = e.args
print(exception_code, exception_message )
print(err.code, err.message)
输出:
<oracledb.Var of type DB_TYPE_NUMBER with value 1> <oracledb.Var of type DB_TYPE_VARCHAR with value 'User-Defined Exception'>
(1, 'User-Defined Exception')
我希望得到如下输出:
(-20001, 'Data violated business logic')
您的包不会在包外传播异常。您引发异常,然后在块的
EXCEPTION
处理程序部分捕获它,并设置 OUT
变量。
如果您想提出错误,那么:
CREATE PACKAGE test_package IS
PROCESSING_ERROR EXCEPTION;
PRAGMA EXCEPTION_INIT(PROCESSING_ERROR, -20001);
PROCEDURE my_procedure(
exception_code OUT NUMBER,
exception_message OUT VARCHAR2
);
END;
/
CREATE PACKAGE BODY test_package IS
PROCEDURE my_procedure(
exception_code OUT NUMBER,
exception_message OUT VARCHAR2
)
IS
BEGIN
RAISE PROCESSING_ERROR;
END;
END;
/
然后,如果您调用该过程,则引发的异常是:
ORA-20001:
号码正确,但没有消息。
如果您想要该消息,请使用
RAISE_APPLICATION_ERROR
(不需要您先声明异常):
CREATE OR REPLACE PACKAGE BODY test_package IS
PROCEDURE my_procedure(
exception_code OUT NUMBER,
exception_message OUT VARCHAR2
)
IS
BEGIN
RAISE_APPLICATION_ERROR(-20001, 'Data violated business logic');
END;
END;
/
那么引发的异常是:
ORA-20001: Data violated business logic
如果您这样做并且没有捕获异常,那么您的代码应该可以工作。
您的代码将是:
CREATE PACKAGE BODY my_package IS
PROCESSING_ERROR EXCEPTION;
PROCEDURE my_procedure(
exception_code OUT NUMBER,
exception_message OUT VARCHAR2
)
IS
row_count number;
BEGIN
--Initialize the return parms.
exception_code := 0;
exception_message := NULL;
SELECT count(*)
INTO row_count -- INTO goes before FROM
FROM my_table;
IF row_count > 0 THEN
RAISE_APPLICATION_ERROR(-20001, 'Data violated business logic');
END IF;
END my_procedure;
END my_package;