对异常类型有一些混淆

Posted

技术标签:

【中文标题】对异常类型有一些混淆【英文标题】:Having some confusion in exception types 【发布时间】:2019-12-20 15:08:54 【问题描述】:

    我们可以使用 USER_DEFINED EXCEPTION 或 PREDEFINED EXCEPTION (others, SQLERRM, SQLCODE) 使用 OUT PARAMETER MODE 将错误消息、错误代码传递给前端,那么为什么我们使用 RAISE_APPLICATION_ERROR 过程?

    RAISE_APPLICATION_ERROR 和 pragma EXCEPTION_INIT 有什么区别?

我已经在 Google 上搜索了这些问题,但无法得到明确的答案 - 这就是为什么在这里发布。

【问题讨论】:

【参考方案1】:

See this similar question。这两个问题的答案是RAISE_APPLICATION_ERROR 是定义要在客户端应用程序中显示的自定义错误消息的规范方法。是的,您还可以使用 OUT 参数或 DBMS_OUTPUT 或类似的东西将自定义消息传回,但这些都不是标准化的 - 您必须在服务器端和客户端添加代码来处理它们。

DECLARE
   my_exception EXCEPTION;
   PRAGMA EXCEPTION_INIT(my_exception, -20001);
BEGIN
   raise my_exception; -- message is default "ORA-20001: "
END;
/

BEGIN
   raise_application_error(-20001, 'My custom error message'); -- message is "ORA-20001: My custom error message"
END;
/

当您想提供更有帮助的描述性错误消息时,这通常很有用。

DECLARE
  age NUMBER;
BEGIN
  age := 'hello';
EXCEPTION when VALUE_ERROR then
  raise_application_error(-20001, 'Age must be a number.');
END;
/

因此,我们可以准确地告诉用户问题所在,而不是通用的“PL/SQL:数字或值错误:字符到数字的转换错误”:“年龄必须是数字”。

【讨论】:

【参考方案2】:

用户定义的异常不会向调用应用程序提供任何消息。它只会得到一个通用的“ORA-06510: PL/SQL: unhandled user-defined exception”。 raise_application_error 可让您传递描述实际问题的消息。

declare
    out_of_stock exception;
begin
    raise out_of_stock;
end;
/

ERROR at line 1:
ORA-06510: PL/SQL: unhandled user-defined exception
ORA-06512: at line 4


begin
    raise_application_error(-20000, 'Cheese is out of stock');
end;
/

ERROR at line 1:
ORA-20000: Cheese is out of stock
ORA-06512: at line 2

pragma exception_init(exception_name, error_code) 允许您将自己的用户定义异常与系统错误代码相关联。从编程的角度来看,这可能很有用,但最终它不会为调用者增加任何价值:

declare
    invalid_day_of_month exception;
    pragma exception_init(invalid_day_of_month, -1847);

    d date;
begin
    d := to_date('99-JAN-2020','DD-MON-YYYY');
exception
    -- Pointless exception handler - just to demo raising a user-defined exception
    when invalid_day_of_month then raise;
end;
/

ERROR at line 2:
ORA-01847: day of month must be between 1 and last day of month
ORA-06512: at line 10
ORA-06512: at line 7

通过 OUT 参数传递成功/失败状态通常是一个坏主意,因为过程看起来已经成功完成,调用者必须读取状态以查看它是否真的成功。

【讨论】:

以上是关于对异常类型有一些混淆的主要内容,如果未能解决你的问题,请参考以下文章

spring - AOP 基础

关于支付类的一些测试关注点及异常点

异常处理 Exception

java-异常处理和线程的一些简单方法及使用

Android混淆总结篇

Java编程中 常见的异常有哪几种