PL/SQL:捕获编号异常?
Posted
技术标签:
【中文标题】PL/SQL:捕获编号异常?【英文标题】:PL/SQL: catching numbered exception? 【发布时间】:2016-01-30 00:52:17 【问题描述】:这是捕获命名异常的规范方法。
begin
select ...;
exception
when zero_divide then
...
end;
如何捕获编号异常?可以在一个when子句中指定多个异常条件吗?
ORA-01555: snapshot too old: ...
ORA-08180: no snapshot found based on specified time
ORA-01466: unable to read data - table definition has changed
【问题讨论】:
使用EXCEPTION_INIT Pragma
,有关详细信息和示例,请参阅此链接:docs.oracle.com/cd/B19306_01/appdev.102/b14261/…。另请参阅此链接:docs.oracle.com/cd/B19306_01/appdev.102/b14261/errors.htm#i9355 以了解处理异常的基础知识。您可以指定多个异常处理程序,只需链接 WHEN .. THEN .. WHEN .. THEN..
等。
【参考方案1】:
我想到的一种可能的方法是在其他处理程序和内部检查 sqlerrm(sqlcode) 时编写一个。
if (sqlerrm(sqlcode) = ORA-01555) then
do this
elsif ....
【讨论】:
它不会有ORA-01555
的值,只有-1555
的数值,据我记得docs.oracle.com/cd/B19306_01/appdev.102/b14261/…。
那是真的,,我的坏。
嗯.. 你的语法绝对不是 PL/SQL。但总的来说这个想法很好。
是的,过去 6 个月我一直在使用 Java 进行编码。我会牢记坚持plsql语法,下次尝试发布语法正确的逻辑。【参考方案2】:
首先,在documentation之后,我们必须说:
每个异常都可以通过
PRAGMA EXCEPTION_INIT
与只有一个错误代码相关联, 并且同一异常的许多 pragma 声明不会获得编译错误,但最新的 pragma 会覆盖所有以前的 pragma。 所以我们没有自然的(或原生的)PL/SQL 方法来将多个异常代码联合到一个异常名称下以能够 用WHEN my_unversal_exception THEN
捕捉它们。
所以当我们想一次捕获许多异常时,没有其他选择,只能进入WHEN OTHERS THEN
部分并执行一些技巧(仅限于想象力)。这已经不是什么秘密了——我们必须处理sqlcode
函数,所以让我们把它做得漂亮并尝试封装这些东西。
可能的解决方案之一:
创建布尔函数,用于检查错误代码(可能还有错误消息),并将它们用作CASE TRUE WHEN ...
中的守卫。
CREATE OR REPLACE PACKAGE exc_filter IS
FUNCTION exception_kind_A RETURN boolean;
FUNCTION exception_kind_B RETURN boolean;
FUNCTION exception_kind_C RETURN boolean;
END;
/
CREATE OR REPLACE PACKAGE BODY exc_filter IS
-- I use negation of sqlcode to reduce noice of minuses.
FUNCTION exception_kind_A RETURN boolean is BEGIN
RETURN -sqlcode IN (01476, 06502);
END;
FUNCTION exception_kind_B RETURN boolean IS BEGIN
RETURN -sqlcode BETWEEN 20010 AND 20020;
END;
-- a bit of discouraging flexibility
FUNCTION exception_kind_C RETURN boolean IS BEGIN
RETURN instr(sqlerrm, 'Yay') > 0;
END;
END;
/
DECLARE
x number;
BEGIN
-- each line raises an error - uncomment to try
x := 5/0;
-- raise_application_error(-20008, 'Yay');
-- raise_application_error(-20015, 'Another');
-- x := to_number('abc');
EXCEPTION WHEN OTHERS THEN -- catch all, then switch
CASE TRUE
WHEN exc_filter.exception_kind_A THEN dbms_output.put_line('Kind A : ' || sqlerrm);
WHEN exc_filter.exception_kind_B THEN dbms_output.put_line('Kind B : ' || sqlerrm);
WHEN exc_filter.exception_kind_C THEN dbms_output.put_line('Kind C : ' || sqlerrm);
ELSE raise; -- strongly recommended line
END CASE;
END;
/
【讨论】:
以上是关于PL/SQL:捕获编号异常?的主要内容,如果未能解决你的问题,请参考以下文章