Python Oracle-db 用户定义的异常

问题描述 投票:0回答:1

我正在从 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')
python oracle
1个回答
0
投票

您的包不会在包外传播异常。您引发异常,然后在块的

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;
© www.soinside.com 2019 - 2024. All rights reserved.