oracle异常、异常捕捉以及异常处理
异常以及处理异常1、概念2、预定义异常1、两数相除,分母为0,捕捉并抛出异常2、值转换异常3、根据姓名查找员工的职位,可能会出现的异常有:没有个这员工,或者有两个或更多的人叫同样的名字。3、非预定义异常4、自定义异常5、课堂练习:1、概念异常是指PL/SQL程序在执行时出现的错误在PL/SQL中的一个警告或错误的情形都被称为异常。提示:编译错误(主要指语法错误)不包含在内。异常处理通常写在执行体的
异常以及处理异常
1、概念
异常是指PL/SQL程序在执行时出现的错误
在PL/SQL中的一个警告或错误的情形都被称为异常。提示:编译错误(主要指语法错误)不包含在内。
异常处理通常写在执行体的最下面,在所有执行语句之后以exception关键字开始异常处理
语法:
Exception
when exception_name then
Statement1
…
when exception_name then
…
when others then --一般是最后一条子句,没有捕捉到的都被它捕捉
…
异常处理部分包含一个或多个when子句,子句中是被捕捉的异常名称
注意: when others then 是可以没有的。
非预定义异常只能编号没有名称
所有的异常都有编号
异常的分类:
异常包括系统异常和自定义异常
系统异常分为预定义异常和非预定义异常
2、预定义异常
是指Oracle已经预先定义好名称的异常。每个预定义异常都有名字和对应的错误码(错误编号)
捕捉预定义异常的方法很简单,直接在程序里按名称捕捉就可以了
oracle 预定义的异常:
1、两数相除,分母为0,捕捉并抛出异常
declare
n1 number(2) := 9;
n2 number(2) :=0;
result number;
begin
result := n1/n2;
dbms_output.put_line(result);
end;
这个时候上面的代码运行的时候会报错,是有异常的。
declare
n1 number(2) := 9;
n2 number(2) :=0;
result number;
begin
result := n1/n2;
dbms_output.put_line(result);
exception
when zero_divide then
dbms_output.put_line('除数不能为0');
end;
上面的代码运行的时候会在控制台抛出“除数不能为0”,这就是抛出异常的过程,上面是进行捕捉异常的过程。
记住两个最常用的异常:NO_DATA_FOUND 、TOO_MANY_ROWS
当在exception段中定义了多个异常时,只会执行一个,之后跳出异常段。
2、值转换异常
SET SERVEROUTPUT ON;
DECLARE
x NUMBER;
BEGIN
x:= 'a123';--向NUMBER类型的变量x中赋值字符串,导致异常
dbms_output.put_line(x);
EXCEPTION
WHEN VALUE_ERROR THEN
DBMS_OUTPUT.PUT_LINE('数据类型错误');
END;
运行结果为:
数据类型错误
PL/SQL 过程已成功完成。
上面出现异常的原因是因为x是number数值型的函数,而在赋值的时候,x被赋予了一个字符串,所以出现了值转换时候的异常。
但是如果将纯数字的字符串赋值给x,x会自动将纯数字的字符串转换为number类型。
3、根据姓名查找员工的职位,可能会出现的异常有:没有个这员工,或者有两个或更多的人叫同样的名字。
declare
v_name emp.ename%type := '&name';
v_job emp.job%type;
begin
select job into v_job from emp where ename=v_name;
dbms_output.put_line(v_name || '的职位是:' || v_job);
exception
when no_data_found then
dbms_output.put_line('没有这个员工');
when TOO_MANY_ROWS then
dbms_output.put_line('有同名的员工');
when others then
dbms_output.put_line('其他异常');
end;
当select语句查询的结果没有数据的时候,就会抛出no_data_found异常,当结果中的数据有多条数据的时候,会抛出TOO_MANY_ROWS,如果存在异常,但不是前面两种异常就会抛出others异常。
异常是通过异常名称来捕获的。
当在exception段中定义了多个异常时,只会执行一个,之后跳出异常段
3、非预定义异常
在数据库中没有定义异常名称的异常
通常都是数据库的错误,这些错误只有错误编号,而没有错误的异常名称,所以不能直接捕捉到
用户在使用这类异常时必须先为它声明一个异常类型的名称,然后通过pragma exception_inin语句为该异常关联错误编号
使用非预定义异常包括三个步骤:
1.在程序块的声明部分定义一个异常名称
2.在声明部分使用伪过程将异常名称和错误编号关联
3.在异常处理部分捕获异常并对异常情况做出相应的处理
伪过程的语法:
pragma exception_init(exception_name,oracle_error_number)
exception_name:异常名称
oracle_error_number:错误代码
例子:
有一个异常:ORA-02292,没有名称,含义是当删除被子表引用的父表中的相关记录时发生。
表emp有外键关联表dept的主键,当部门10有员工时,不能删除部门10。如果我们做了这样的操作,就违反了约束条件。
父表:dept表
子表:emp表
delete from dept where deptno=10;
提示:违反完整性约束条件
declare
myexception exception;
pragma exception_init(myexception,-02292);
begin
delete from dept where deptno=10;
exception
when myexception then
dbms_output.put_line('10部门有员工,不能删除');
when others then
dbms_output.put_line('其他异常');
end;
4、自定义异常
用户在实际的开发中,可能会有一些业务逻辑上的规定,如果违反了这些规定,则会发生异常
如何定义和使用自定义异常?
异常定义
在声明部分采用exception关键字声明异常:myexception exception
异常引发
在程序执行体部分,使用raise关键字进行引发:
raise myexception
举例:
在emp表中查询james的工资,如果工资小于5000,则引发自定义异常
DECLARE
myexception EXCEPTION;
v_sal emp.sal% TYPE;
BEGIN
select sal into v_sal from emp where ename='JAMES';
IF v_sal<5000 THEN
raise myexception;
end if;
dbms_output.put_line('JAMES的工资是:'||v_sal);
EXCEPTION
when myexception then
dbms_output.put_line('工资太少了');
when no_data_found THEN
dbms_output.put_line('没有这个员工');
END;
使用用户自定义异常,同样需要在声明部分定义异常的名称,然后在执行体中,通过一些逻辑判断决定是否违反了用户的规则,如果违反规则,则调用raise命令人为触发自定义的异常,并在异常处理部分捕捉到这个异常进行处理。
显然:raise语句应该与if语句一起使用。
5、课堂练习:
根据员工编号对emp表修改员工的奖金,当员工原本有奖金,则再增加100元,如果原来没有奖金,则抛出异常,说明奖金为空。
declare
myexception exception;
v_comm emp.comm%type;
v_empno emp.empno%type :=&a;
begin
select comm into v_comm from emp where empno=v_empno;
if v_comm is null then
raise myexception;
end if;
dbms_output.put_line(v_comm);
EXCEPTION
when myexception then
dbms_output.put_line('MEIYOUjiangJIN');
when no_data_found THEN
dbms_output.put_line('没有这个员工');
END;
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)