77范文网 - 专业文章范例文档资料分享平台

Oracle PLSQL 异常处理

来源:网络收集 时间:2020-05-08 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:或QQ: 处理(尽可能给您提供完整文档),感谢您的支持与谅解。点击这里给我发消息

PL/SQL 异常处理的概念和术语

在 Oracle 中所有的错误都被认为是不应该发生的异常。一个异常可能是以下 3 种情况的一种: 1〉由系统产生的错误(“ out of memory “ 或 “ duplicate value in index “) 2〉用户行为导致的错误 3〉应用程序给用户的一个警告

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 是一个未被定义的变量,所以将产生一个错误,并将给异常处理模块处理。

从异常的可应用范围出发,可将异常分为两类: 1、系统异常:

由 Oracle 定义并由 PL/SQL Runtime 引擎在检测到错误时产生的异常。一些系统异常有名字,比如 NO_DATA_FOUND,然而大多数的异常仅仅只有数字编号和描述。这些异常无论在哪个 PL/SQL 中程序都能被应用。

共有 21 个命名的系统异常,见下表:

1

命名的系统异常 ACCESS_INTO_NULL CASE_NOT_FOUND COLLECTION_IS_NULL CURSER_ALREADY_OPEN DUP_VAL_ON_INDEX INVALID_CURSOR INVALID_NUMBER NO_DATA_FOUND TOO_MANY_ROWS ZERO_DIVIDE SUBSCRIPT_BEYOND_COUNT SUBSCRIPT_OUTSIDE_LIMIT VALUE_ERROR LOGIN_DENIED NOT_LOGGED_ON PROGRAM_ERROR ROWTYPE_MISMATCH SELF_IS_NULL STORAGE_ERROR SYS_INVALID_ID TIMEOUT_ON_RESOURCE 产生原因 未定义对象 CASE 中若未包含相应的 WHEN ,并且没有设置 ELSE 时 集合元素未初始化 游标已经打开 唯一索引对应的列上有重复的值 在不合法的游标上进行操作 内嵌的 SQL 语句不能将字符转换为数字 使用 Select into 未返回行,或应用索引表未初始化的元素时 执行 Select into 时,返回超过一行 除数为 0 元素下标超过嵌套表或 VARRAY 的最大值 使用嵌套表或 VARRAY 时,将下标指定为负数 赋值时,变量长度不足以容纳实际数据 PL/SQL 应用程序连接到 Oracle 数据库时,提供了不正确的用户名或密码 PL/SQL 应用程序在没有连接 Oracle 数据库的情况下访问数据 PL/SQL 内部问题,可能需要重装数据字典& PL/SQL 系统包 宿主游标变量与 PL/SQL 游标变量的返回类型不兼容 使用对象类型时,在 Null 对象上调用对象方法 运行 PL/SQL 时,超出内存空间 无效的 ROWID 字符串 Oracle 在等待资源时超时 2、由程序员定义的异常: 程序员在程序中定义的异常,它只是在特定的程序种有效。可以使用 EXCEPTION_INT 这个 Pragma 将一个无名字的系统异常与一个程序员定义的名字相关联。或者用 RAISE_APPLICATION_ERROR 来自定义一个异常的数字编号和描述。 按异常生成方式可分为: 1、预定义异常: 就是上面表中的 21 种有名字的系统异常。 2 2、非预定义异常:

没名字的系统异常,可以用 Pragma Exception_Int 给它关联一个名字。

3、自定义异常:

需要用 RAISE 或 RAISE_APPLICATION_ERROR 生成的异常。

下面是一些要用到的属于 ;

Exception section (异常处理模块)

它是PL/SQL语句块种包含一个或多个异常句柄的部分。Exception section的结构基本上与case 相似。 Raise (产生)

通过通知 PL/SQL Runtime 引擎有错误来中止当前程序的运行,也可通过显式的请求,如: RAISE 或 RAISE_APPLICATION_ERROR 来触发异常。 Handle (句柄,某一个异常处理的代码)

在 exception section 中捕捉错误。可以在 handle 中编写程序来处理异常,比如将错误记入 log 中,显示一个错误信息,将异常传出当前程序快。 Scope (作用范围 )

一个异常从产生、被捕捉到处理整个过程所处的程序部分。

Propagation (传递)

如果一个异常没有被处理,那么它将被传递到但前块的上一级,它有可能是另一个代码快,也可能是系统。 Unhandled exception (未被处理的异常)

如果一个异常没有被处理,并一直被传递道理系统中,那么它被称为 unhandled exception 。 Un-named or anonymous excepttion (匿名异常)

(在异常类型中有介绍)

Named exception (命名异常)

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

3

异常定义

在一个异常产生、被捕获并处理之前,它必须被定义。 Oracle 定义了几千个异常,绝大多数只有错误编号和相关描述,仅仅命名了若干个最常被用到的异常。这些名字被储存在 STANDARD、UTL_FILE、DBMS_SQL 这几个系统包中,详情请见 上节《PL/SQL 异常处理的概念和术语》。 除此之外的绝大多数异常需要程序员命名。

有 2 种命名异常的方法: 1、声明一个自定义异常:

在 STANDARD 中的命名了的异常基本上是与系统的错误相关的(当然那些只有 errorcode 的异常也是这样),但在实际的应用中我们经常需要与特定的应用程序相关的异常,由程序员声明的异常就是用于处理这种情况的。

Oracle 异常处理模块的方便的之处在于,它并没有区分对待自定义的与预定义的异常。这使得我们可以像对待预定义异常一样,捕捉和处理自定义异常,只是在捕捉和处理自定义异常之前需要声明它;同时对于一个自定义的异常,我们需要用 RAISE 来手动产生。 下面是一个声明的例子:

procedure calc_ammul_sales(company_id_in in company.company_id%tye) is

invalid_company_id exception; negative_balance excrption; duplicate_company Boolean; begin

/*body of executable statement*/ exception

when invalid_company_id then /*handle exception*/ when no_data_found then /*handle exception*/ /*…..*/ end;

需要注意的是处理定义异常的时候,只有两个地方会出现自定义的异常: ? raise exception; 与 when exception then 2、为非预定义异常关联一个名字:

4

仅仅 21 个预定义异常对我们来说实在是太少了,还有几千个异常只有 errorcode 和描述。另外,程序员也可以用 RAISE_APPLICATION_ERROR 定义一个含 errorcode 和描述的异常。

当然,只用 errorcode 也可以很好地完成工作,只要你不担心会忘了那串数字代表的意思就行。比方说 ;

Begin ……. exception

when others then

/* SQLCode 是内建的用于返回最近一次错误编号的函数 */ if SQLCode=-1843 then ….. End;

很显然这是一段让人感到晦涩的代码,还是给它关联个名字吧。

我们要用到的是 PRAGMA EXCEPTION_INIT(EXCEPTION,INTEGER) ,然后就可以像对待预定义异常一样对待它了,我是说没必要像上面的那种一样用 RAISE。EXCEPTION_INIT 是一个编译时运行的函数,它只能出现在代码的声明部分,而异常名字必须在此之前被定义。下面用一个匿名过程举个例子:

declare

invalid_company_id exception;

Pragma exception_init(invalid_company_id, -1834);

需要注意的是:值不可以用 -20000 ~ -20999之外的值,这个范围是Oracle预留给程序员使用的,事实上 EXCEPTION_INIT 中的 Integer 对应的是 SQLCode 返回的值。

Procedure delete_company(company_id_in in number) is

still_have_emplyee exception;

Pragma exception(still_have_employee, -2293); begin delete from compamy where company_id=company_id_in; exception when still_have_employee then

dbms_output.put_line(‘delete employees for company first’);

end;

在以下两种情况,有必要使用 EXCEPTION_INIT : ?一个非预定义异常是经常要被用到的。

? 我们将用 raise_applocation_error 产生了一个自定义的 errorcode 时。

一种简便的方法是将以上两种情况中的异常定义在一个包中,这样我们就没有必要每次都重复定义了。

CREATE OR REPLACE PACKAGE DYNSQL IS

INVALID_TABLE_NAME EXCEPTION;

5

百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说教育文库Oracle PLSQL 异常处理在线全文阅读。

Oracle PLSQL 异常处理.doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.77cn.com.cn/wenku/jiaoyu/1035544.html(转载请注明文章来源)
Copyright © 2008-2022 免费范文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ: 邮箱:tiandhx2@hotmail.com
苏ICP备16052595号-18
× 注册会员免费下载(下载后可以自由复制和排版)
注册会员下载
全站内容免费自由复制
注册会员下载
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: