一、异常概述
关于异常概述,包括以下知识点:
1、异常的概念
异常:程序运行时出现的错误
发生时机:发生了ORACLE错误会触发或者使用RAISE语句显示触发
发生后现象:终止当前语句的执行,控制权注意到异常处理部分
如何处理异常:使用处理机制截获或者在调用环境中传播
2、异常的分类
预定义异常:Oracle服务器事先定义好的异常,不需要声明,会隐式触发
自定义异常:开发者自己定义的异常,PL/SQL块声明部分声明,在语句中显示的触发
3、常见异常的发生时机(不包括自定义异常,常见的异常都是预定义异常)
NO_DATA_FOUND:执行查询无结果
TOO_MANY_ROWS:使用SELECT…INTO时,返回结果超出1条
ZERO_DIVIDE:除以0
TIMEOUT_ON_RESOURCE:等待资源超时
CURSOR_ALREADY_OPEN:打开一个已经打开的游标
INVALID_CURSOR:引用一个无效游标
…
演示异常例子对异常有一个感性的认识
declare
x number := 12;
y number := 0;
begin
dbms_output.put_line('a');
x := x/y;
dbms_output.put_line('b');
exception
when zero_divide then
dbms_output.put_line('zero divided.'||x||' '||y);
end;
declare
x number := 12;
y number := 0;
v_sal emp.sal%type;
begin
dbms_output.put_line('a');
--x := x/y;
select sal into v_sal
from emp
where deptno = 10 ;
dbms_output.put_line('b');
exception
when too_many_row then
dbms_output.put_line('too many rows are selected, use cursor please.');
when no_data_found then
dbms_output.put_line('not any data found');
end;
二、异常处理
关于异常处理,包含以下知识点:
1、自定义异常
PL/SQL中允许用户自定义异常
自定义异常必须:
在PL/SQL块的声明部分声明
使用RAISE语句显示的触发
2、异常的引发
预定义异常会在出错时自动引发
自定义异常需要先定义,然后触发
定义:myexception EXCEPTION;
引发:RAISE myexception;
3、异常的处理
自定义异常的处理形式
DECLARE
myerr EXCEPTION
BEGIN
…
RAISE myerr;
EXCEPTION
WHEN myerr THEN
…
END;
注:如果是预定义异常的话,它相对于自定义异常就简单的多。不需要再DECLARE中声明,也不需要在BEGIN中RAISE引发我们的异常,我们只需要正常的执行我们的程序就可以,一旦出错了会自动跳到EXCEPTION子句中,找到对应的处理语句进行处理 。
EXCEPTION子句用于进行异常处理,其中:
WHEN 异常类型 THEN:用于匹配指定的异常
WHEN OTHERS THEN:用于匹配其余的异常
关于异常处理有两个函数,需要了解:
SQLCODE:返回异常错误码,表示错误的一个负数
SQLERRM:返回错误码和异常信息
只能在PL/SQL异常处理块中使用,不能在SQL中直接使用这两个函数
预定义异常的一般处理形式:
declare
v_sal emp.sal%type;
begin
select sal into v_sal
from emp
where empno = 99;
dbms_output.put_line('sal is'||v_sal);
exception
WHEN no_data_found then
dbms_output.put_line('error occured!');
dbms_output.put_line(SQLCODE || ':::' || SQLERRM);
END;
自定义异常的一般处理形式:
declare
v_sal emp.sal%type;
saltoohigh Exception;
begin
select sal into v_sal
from emp
where empno = 7566;
if v_sal > 2500 then
raise saltoohigh;
end if;
exception
WHEN no_data_found then
dbms_output.put_line('error occured!');
dbms_output.put_line(SQLCODE || ':::' || SQLERRM);
WHEN saltoohigh then
dbms_output.put_line('v_sal is too high');
WHEN others then --必须放在其它异常处理语句的后面,否则会出现错误(可以处理任意类型的异常)
dbms_output.put_line('other exception occured!');
END;
三、异常的传播与使用准则
关于异常的传播和使用准则,包含以下知识点:
1、异常的传播
发生异常的PL/SQL块会将异常传播给外部块或者调用者
若异常处理中需要异常继续传播,可以通过RAISE子句来完成
begin
declare
v_sal emp.sal%type;
begin
select sal into v_sal
from emp
where deptno = 10 ;
end;
exception
when too_many_rows then
dbms_output.put_line(SQLERRM);
end;
end;
declare
myerr EXCEPTION
begin
declare
v_sal emp.sal%type;
begin
select sal into v_sal
from emp
where deptno = 10 ;
exception
when OTHERS then
raise myerr;
end;
exception
when myerr then
dbms_output.put_line('error ocurred! please contract the administrator.');
end;
end;
2、使用异常的准则
允许同时处理多个异常
WHEN exception OR exception THEN …
WHEN OTHERS子句书写在最后