前几天看《Oracle PL/SQL Programming》的异常处理部分,粗粗看了一遍,觉得有点乱,根据自己的理解作了一下分类,并相应给了一些简例,不一定很准确,供参考。
Oracle 异常 |
具名Oracle异常 |
Oracle为此类异常预先指定了异常号、异常信息、异常名称 |
匿名Oracle异常 |
Oracle为此类异常预先指定了异常号、异常信息、但未指定异常名称 |
|
自定义异常 |
普通自定义异常 |
与Oracle无关的业务逻辑异常,无异常号、异常信息,异常名称需要手工声明 |
应用程序异常(Raise_Application_Error) |
与Oracle无关的业务逻辑异常,此方法抛出的异常可以自定义异常号及异常信息,可以通过Exception_Init绑定到手工声明的异常名称上 |
1)Oracle异常
Oracle异常总是由Oracle检测并自动抛出的。
1.1)具名Oracle异常
Oracle定义了21个具名的Oracle异常,比如:
Dup_val_on_index(ora-00001)当中唯一索引所对应的列上键入重复值时。
No_data_found(ora-01403)执行select into未返回行,或者引用了索引表未初始化的元素时。
流程:
A)在Exception模块按异常名进行处理
示例:
num number;
BEGIN
num:=1/0;
EXCEPTION
when ZERO_DIVIDE then
dbms_output.put_line(SQLERRM);
END;
/
ORA-01476: divisor is equal to zero
PL/SQL procedure successfully completed
1.2)匿名Oracle异常
Oracle中存在大量匿名的异常,比如:
ORA-02291: parent key not found
由于PL/SQL的异常处理模块只接受异常名称,不接受异常号(除了WHEN OTHERS语句,它可以捕获任意异常,不论你是否具有异常名称),为便于处理,需要手工为其指定异常名称。
流程:
A)声明异常
B)将此异常绑定到Oracle异常号上
C)在Exception模块按异常名进行处理
示例:
ex EXCEPTION;
PRAGMA EXCEPTION_INIT(ex,-2291);
BEGIN
insert into t2 values(2);
EXCEPTION
when ex then
dbms_output.put_line(SQLERRM);
END;
/
ORA-02291: integrity constraint (ADMIN.FK1) violated - parent key not found
PL/SQL procedure successfully completed
2)自定义异常
自定义异常总是开发者显式抛出来的。
2.1)普通自定义异常
流程:
A)声明异常
B)使用Raise语句抛出异常
C)在Exception模块按异常名进行处理
示例:
ex EXCEPTION;
BEGIN
RAISE ex;
EXCEPTION
when ex then
dbms_output.put_line(SQLERRM);
dbms_output.put_line('i raised a user-defined exception ''ex''');
END;
/
User-Defined Exception
i raised a user-defined exception 'ex'
2.2)应用程序异常Raise_Application_Error(Num, Msg)
普通自定义异常既没有异常号(SQLCODE一律为1),也不能指定异常信息(SQLERRM一律为‘User-Defined Exception’),如果想要为自定义异常指定异常号与异常信息,需要借助Raise_Application_Error(Num, Msg)函数,这里的Num即异常号,范围是[-20999,-20000],Msg则是异常信息。
对于此类异常,由于Num是自定义的,因此应该有相应的管理办法以避免重复使用异常号,比如可以将已使用的异常号保存在一张数据库中表,以便将来检查。
流程:
A)声明异常
B)将此异常绑定到自定义的异常号上
C)使用Raise_Application_Error(Num, Msg)抛出异常,同时指定了异常号及异常信息
D)在Exception模块按异常名进行处理
示例:
is
ex EXCEPTION;
PRAGMA EXCEPTION_INIT(ex, -20001);
BEGIN
Raise_Application_Error(-20001,'raising my exception.');
EXCEPTION
when ex then
dbms_output.put_line(SQLERRM);
END;
/
Procedure created
SQL> exec mtest
ORA-20001: raising my exception.
PL/SQL procedure successfully completed