pl/sql
提供了强大而灵活的手段来捕捉和处理程序产生的异常,从而使
oracle
的用户远离一些令人烦恼的
bug
。
pl/sql
异常处理的概念和术语
在
oracle
中所有的错误都被认为是不应该发生的异常。一个异常可能是以下
3
种情况的一种:
u
由系统产生的错误(“
out of memory
”或“
duplicate value in index
”)
u
用户行为导致的错误
u
应用程序给用户的一个警告
pl/sql
用一种异常句柄的结构来捕捉和响应错误。正是有了异常句柄的存在,我们能很方便的分离异常处理代码与可执行代码。与线性的代码相比,为了处理异常,异常句柄提供了一种类似事件驱动的模式;换句话说,就是不管一种特定的错误在何时何地发生,它都将被同一个代码处理。
当一个错误出现后,无论它是系统还是程序产生的,都将导致一个异常。之后,可执行程序被中断,控制权转移给异常处理代码。处理完异常后,程序将不会回到先前被中断的位置,相反的,控制权被交给了当前程序的外围模块(可能是程序,也可能是系统)。
procedure jimmy
is
new_value varchar(35)
begin
|--------new_value:=old_value || ‘-new’;
| if new_value like ‘like%’
| then
| …..
| end if;
| exception
|-----
à
when value_error
then
…..
end;
因为
old_value
是一个未被定义的变量,所以将产生一个错误,并将给异常处理模块处理。
从异常的可应用范围出发,可将异常分为两类:
系统异常:
由
oracle
定义并由
pl/sql runtime
引擎在检测到错误时产生的异常。一些系统异常有名字,比如
NO_DATA_FOUND
,然而大多数的异常仅仅只有数字编号和描述。这些异常无论在哪个
pl/sql
中程序都能被应用。
共有
21
个命名的系统异常:
命名的系统异常
|
产生原因
|
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 iotn
时,返回超过一行
|
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
在等待资源时超时
|
由程序员定义的异常:
程序员在程序中定义的异常,它只是在特定的程序种有效。可以使用
EXCEPTION_INT
这个
pragma
将一个无名字的系统异常与一个程序员定义的名字相关联。或者用
RAISE_APPLICATION_ERROE
来自己定义一个异常的数字编号和描述。
按异常生成方式可分为:
预定义异常:
就是上面表中的
21
种有名字的系统异常。
非预定义异常:
没名字的系统异常,可以用
pragma exception_int
给它关联一个名字。
自定义异常:
需要用
RAISE
或
RAISE_APPLICATION_ERROR
生成的异常。
下面是一些要用到的属于
;
Exception section
(异常处理模块)
它是
pl/sql
语句块种包含一个或多个异常句柄的部分。
Exception section
的结构基本上与
case
相似。
Raise
(产生)
通过通知
pl/sql runtime
引擎有错误来中止当前程序的运行。也可通过显式的请求,如:
RAISE
或
RAISE_APPLICATION_ERROR
来
RAISE
一个异常。
Handle
(句柄,某一个异常处理的代码)
在
exception section
中捕捉错误。可以在
handle
中编写程序来处理异常,比如将错误记入
log
中,显示一个错误信息,将异常传出当前程序快。
Scope
(作用范围
)
一个异常从产生、被捕捉到处理整个过程所处的程序部分。
Propagation
(传递)
如果一个异常没有被处理,那么它将被传递到但前块的上一级,它有可能是另一个代码快,也可能是系统。
Unhandled exception
(未被处理的异常)
如果一个异常没有被处理,并一直被传递道理系统中,那么它被称为
unhandled exception
。
Un-named or anonymous excepttion
(匿名异常)
(在异常类型中有介绍)
Named exception
(命名异常)
包括系统异常中有名字的那部分和用户定义的名字。