pl/sql异常处理

抛出异常
Oracle有三种类型的异常错误:
1. 预定义(Predefined)异常
ORACLE预定义的异常情况大约有24个。对这种异常情况的处理,无需在程序中定义,由ORACLE自动将其引发。
2. 非预定义(Predefined)异常
即其他标准的ORACLE错误。对这种异常情况的处理,需要用户在程序中定义,然后由ORACLE自动将其引发。
3. 用户定义(User_define)异常
程序执行过程中,出现编程人员认为的非正常情况。对这种异常情况的处理,需要用户在程序中定义,然后显式地在程序中将其引发。


在PL/SQL中有三种方式抛出异常
通过PL/SQL运行时引擎——抛出Oracle异常

使用RAISE语句——抛出用户定义异常

调用RAISE_APPLICATION_ERROR存储过程——抛出用户定义异常

1、预定义异常是指oracle系统为一些常见错误定义好的异常,例如表中的主键值重复,以及除数为0等。

oracle预定义异常:

命名的系统异常

产生原因

ACCESS_INTO_NULL

未定义对象

CASE_NOT_FOUND

CASE 中若未包含相应的 WHEN ,并且没有设置 ELSE 

COLLECTION_IS_NULL

集合元素未初始化

CURSER_ALREADY_OPEN

游标已经打开

DUP_VAL_ON_INDEX

唯一索引对应的列上有重复的值

INVALID_CURSOR

在不合法的游标上进行操作

INVALID_NUMBER

内嵌的 SQL 语句不能将字符转换为数字

NO_DATA_FOUND

使用 select into 未返回行,或应用索引表未初始化的元素时

TOO_MANY_ROWS

执行 select into 时,结果集超过一行

ZERO_DIVIDE

除数为 0

SUBSCRIPT_BEYOND_COUNT

元素下标超过嵌套表或 VARRAY 的最大值

SUBSCRIPT_OUTSIDE_LIMIT

使用嵌套表或 VARRAY 时,将下标指定为负数

VALUE_ERROR

赋值时,变量长度不足以容纳实际数据

LOGIN_DENIED

PL/SQL 应用程序连接到 oracle 数据库时,提供了不正确的用户名或密码

NOT_LOGGED_ON

PL/SQL 应用程序在没有连接 oralce 数据库的情况下访问数据

PROGRAM_ERROR

PL/SQL 内部问题,可能需要重装数据字典& pl./SQL 系统包

ROWTYPE_MISMATCH

宿主游标变量与 PL/SQL 游标变量的返回类型不兼容

SELF_IS_NULL

使用对象类型时,在 null 对象上调用对象方法

STORAGE_ERROR

运行 PL/SQL 时,超出内存空间

SYS_INVALID_ID

无效的 ROWID 字符串

TIMEOUT_ON_RESOURCE

Oracle 在等待资源时超时

TOO_MANY_ROWS

SELECT INTO 语句返回多条记录

VALUE_ERROR

发生算术,转换,截断或大小约束错误

ZERO_DIVIED

视图讲0作为除数

例9.19在pl/sql中将一个无法表示有效数字的字符转换为数字,如下:

declare
age varchar2(4) := '14岁';
begin
dbms_output.put_line('测试异常发生前的内容有没有执行');
dbms_output.put_line(cast(age as number));
dbms_output.put_line('测试异常发生后的内容有没有执行');
end;

执行的结果:


注意:从执行的结果可以看出,oracle抛出ora-06502异常,提示字符到数值的转换错误,在抛出异常后,由于程序中中没有处理该异常的代码,因此程序终止,所以最后的结果是异常发生前的内容被执行,而之后的内容没有被执行。


对上面的代码进行异常处理:

declare
age varchar2(4) := '14岁';
begin
dbms_output.put_line('测试异常发生前的内容有没有执行');
dbms_output.put_line(cast(age as number));


exception
        when VALUE_ERROR then
dbms_output.put_line('异常提示:该字符串不能转换为有效的数字');

dbms_output.put_line('测试异常发生后的内容有没有执行');
end;


执行的结果:

测试异常发生前的内容有没有执行
异常提示:该字符串不能转换为有效的数字
测试异常发生后的内容有没有执行

2、非预定义异常

除了oracle预定义好的异常以外,还有一些其他异常也属于程序本身的逻辑错误,

例如违反表的外键约束、检查约束等,oralce只为这些异常提供了错误代码,而这些异常同样需要处理,只不过学哟啊在pl/sql块中使用pragma execption_init语句为该异常设置名称

declare
sex_check exception;
pragma exception_init(sex_check,-2290);
begin
insert into student values('路');
exception
when sex_check then
dbms_output.put_line('插入的值违反了sex列的检查约束');
end;
/


3、自定义异常

前面提到的异常主要是程序本身的逻辑错误,而在实际应用中,程序员还可以根据需求,为实现具体的业务逻辑自定义相关异常,因为这些业务逻辑是oracle系统无法判断的,例如:不允许删除管理员表中的最该管理员等。



--例9.21假设manager表中有3列。mid(主键列),mname(管理员名称)和mgrade(管理员级别),要求在根据mid值
--删除manager表中的几率是,不能删除mgrade值为1的记录,
--否则返回异常信息这就需要为也为逻辑穿件自定义异常
declare


manager_id number :=1;
manager_grade number;
begin
select mgrade into manager_grade from manager
where mid=manager_id;
if(manager_grade is not null)and (manager_grade=1)
then raise_application_error(-20100,'不能删除管理级别为1的管理员');
end if;
delete from manager where mid=manager_id;
end;

























评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值