在Oracle中exception关键字,Oracle Error Handling(Oracle 异常处理)

今天被企业导师要求在之前编写的存储过程中加入异常处理的语句, 以增强代码的健壮性.  研究了下 Oracle11g 官方文档, 再做一个简单的实践就解决了. 还是写个博客理理思路, 毕竟好记性不如烂笔头. 由于篇幅和时间关系, 这里只结合部分实例对Oracle的异常处理做一个大概的介绍,  想要完全完整学习Oracle异常处理请自行参阅 Oracle11g官方文档. 如果只是想快速上手异常处理, 不想看概念, 请直接查看本文实例.

一.Oracle支持三种类型的异常: 内部定义异常, 预定义异常 和 用户自定义异常

内部定义异常 是 Oracle 数据库异常信息集 中已经定义好了的异常信息,  由系统自行抛出( 隐式抛出 ). 这种类型的异常只拥有异常代码(error code 如ORA-27102), 没有异常名称, 除非我们给它一个名称 或 PL/SQL给它一个名称. 因此也被称为非预定义内部定义异常(这么叫的原因请看预定义异常概念).

预定义异常其实就是拥有自己的异常名(error name)的内部定义异常, 所以其实是预定义内部定义异常. 比如 ORA-06500就拥有自己的名字 STORAGE_ERROR

自定义异常自然就是根据我们需要而定义的异常, 需要我们自己在代码中抛出(使用 raise 关键字, 显示抛出). 比如 我们规定 a < b是不合法的, 那么我们就可以使用一个if 语句来判断, 当 a < b的时候,就抛出我们自定义的异常, 并做处理.

二.错误信息的获取

在Oralce中, 我们可以使用和这两者都是过程化函数, 不能在SQL中直接使用, 只能将它们的返回值先赋给局部变量(如 mypara := sqlcode ), 再使用这些局部变量.

三.处理异常可以分为根据异常名来做针对性的处理 和只使用others 对异常做一个笼统的处理两种情况.

1) 使用异常名称做针对性处理 (可用于处理拥有异常名称的异常: 自定义异常, 预定义异常, 被给予了名称的内部定义异常)

注:对于没有异常名的内部定义异常,  如果我们大概知道可能会抛出的异常,  并且知道异常的代码, 我们可以给予异常名称, 使用异常名称来做针对性的异常处理.

实例1:定义名称为 my_exception 的自定义异常, 使用raise关键字抛出, 捕获后针对异常名做一个处理.

-- author: csdn libertine1993

create or replace procedure pro_selfdefinde_exp

as

my_exception exception; --定义自定义异常名称

para1 number := 1;

para2 number := 2;

begin

if para1 < para2 then --这里我们规定para1 < para2是不合法的, 使用raise抛出异常 my_exception

raise my_exception;

end if;

exception

when my_exception then

insert into my_error_info(f_id, f_error_msg)

values(sys_guid(), '使用my_exception异常名, 捕获到了异常!');

end pro_selfdefinde_exp;

我们知道异常的名字是my_exception, 可以在捕获的时候做一些针对性的处理, 这里的针对性处理就是插入一条有针对性的描述的记录.于是我们可以看到下面这条记录

0818b9ca8b590ca3270a3433284dd417.png

实例2:使用预定义异常的名字处理异常, 由于预定义异常属于内部定义异常, 因此异常的抛出是系统隐式的自动抛出, 不需要使用raise关键字

Oracle中预定义下面一个预定义异常: (左往右分别是 异常名和异常代码)

0818b9ca8b590ca3270a3433284dd417.png

-- author: csdn libertine1993

create or replace procedure pro_preddefine_exp

as

para1 number := 1;

para2 number := 0;

para3 number;

error_code number;

error_msg varchar(64);

begin

para3 := para1 / para2; --系统将会隐式的抛出 除数为0的异常

exception

when zero_divide then

insert into my_error_info(f_id, f_error_msg)

values(sys_guid(), '这是使用预定义的异常名 zero_divide 捕获到的异常');

END PRO_PREDDEFINE_EXP;

结果:

0818b9ca8b590ca3270a3433284dd417.png

2) 不给于异常名称, 只以others 关键字来对所有异常做一个笼统的处理.

实例:尝试插入一条没有主键的记录, 捕获异常后, 只使用others做一个笼统的处理, 这里的处理是将异常信息插入我们自己建的my_error_info表.

-- author: libertine1933 from csdn

-- 尝试将一条缺少主键的记录插入 mytest表, 获取抛出的异常并将异常信息插入 my_error_info表

create or replace procedure pro_testexception

AS

errorcode number; --异常代码

errormesg varchar2(64); --异常信息

begin

--为了便于观察, 每次都会清空错误信息表内之前的记录

delete from my_error_info;

insert into mytest(f_price) values('123'); --mytest表

exception

when others then --使用others而不是异常名, 因此我们只能对异常做一个笼统的操作

errorcode := sqlcode; --使用sqlcode 和 sqlerrm 必须先赋值给两个局部变量

errormesg := substr(sqlerrm, 1, 64);

insert into my_error_info(

f_id, --自己建的错误信息表中每条记录的ID, 由sys_guid()生成

f_create_date, --记录创建日期, 由sysdate生成

f_error_code, --错误代码

f_error_msg --错误信息

)

values(

sys_guid(),

sysdate,

errorcode,

errormesg

);

END PRO_TESTEXCEPTION;

由于 mytest表 的主键 F_CMID 不能为空, 所以插入失败,  系统自行抛出一个异常(这种常见的异常属于内部定义异常, 由系统自动抛出), 由于使用的是others, 我们并不能得知异常的具体归属, 所以只能做一个笼统的处理, 这里的笼统处理就是将异常信息记录在表中, 这样我们就能够看到下面这条记录:

0818b9ca8b590ca3270a3433284dd417.png

最后, 本文只是对Oracle异常处理做了一个大概的介绍, 关于Oracle中异常的传播, 重定义预定义异常等知识点, 有兴趣继续了解的请参阅Oracle 11g官方文档, 在此不做阐述.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值