对异常类型有一些混淆
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 参数传递成功/失败状态通常是一个坏主意,因为过程看起来已经成功完成,调用者必须读取状态以查看它是否真的成功。
【讨论】:
以上是关于对异常类型有一些混淆的主要内容,如果未能解决你的问题,请参考以下文章