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 (命名异常)

       包括系统异常中有名字的那部分和用户定义的名字。

Posted on 2006-10-25 16:17 艾凡赫 阅读(1546) 评论(0)  编辑 收藏 引用 所属分类: ORACLE

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理