Oracle异常处理

前端之家收集整理的这篇文章主要介绍了Oracle异常处理前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

在编写PL/sql程序时,避免不了会发生一些错误,可能是程序设计人员自己造成的,也可能是操作系统或硬件环境出错,比如出现除数为零、磁盘I/O错误等情况。对于出现的这些错误,Oracle采用异常机制来处理,异常处理代码通常放在PL/sql的EXCEPTION代码块中。根据异常产生的机制和原理,可将Oracle系统异常分为预定义异常和自定义异常。

1、预定义异常

当PL/sql程序违反了Oracle系统内部规定的设计规范时,就会自动引发一个预定义的异常,例如,当除数为零时,就会引发“ZERO_DIVIED”异常。Oracle系统常见的预定义异常及其说明如下:

ZERO_DIVIDE:除数为零时引发的异常。

ACCESS_INTO_NULL:企图为某个未初始化对象的属性赋值。

COLLECTION_IS_NULL:企图使用未初始化的集合元素。

CURSOR_ALREADY_OPEN:企图再次打开一个已经打开过的游标,但在重新打开之前,游标未关闭

INVALID_CURSOR:执行一个非法的游标操作,例如,关闭一个未打开的游标。

INVALID_NUMBER:企图将一个字符串转换成一个无效的数字而失败。

LOGIN_DENIED:企图使用无效的用户名或密码连接数据库

NO_DATA_FOUND:SELECT INTO语句没有返回数据。

ROWTYPE_MISMATCH:主游标变量与PL/sql游标变量的返回类型不兼容。

SELF_IS_NULL:使用对象类型时,使用空对象调用方法

SUBSCRIPT_BEYOND_COUNT:元素下标超过嵌套表或VARRAY的最大值。

SUBSCRIPT_OUTSIDE_LIMIT:企图使用非法索引号引用嵌套表或VARRAY中的元素。

SYS_INVALID_ROWID:字符串向ROWID转换时的错误,因为该字符串不是一个有效的ROWID值。

TIMEOUT_ON_RESOURCE:Oracle在等待资源时超时。

TOO_MANY_ROWS:执行SELECT INTO语句时,结果集超过一行引发的异常。

【实例】使用SELECT INTO语句检索emp表中部门编号为10的雇员记录信息,然后使用“TOO_MANY_ROWS”预定义异常捕获错误信息并输出

declare
  var_empno number;         --定义变量,存储雇员编号
  var_ename varchar2(50);   --定义变量,存储雇员名称
begin
  select empno,ename into var_empno,var_ename
  from emp
  where deptno=10;          --检索部门编号为10的雇员信息
  if sql%found then         --若检索成功,则输出雇员信息
    dbms_output.put_line('雇员编号:'||var_empno||';雇员名称:'||var_ename);
  end if;
  exception                 --捕获异常
    when too_many_rows then
      dbms_output.put_line('返回记录超过一行');
    when no_data_found then
      dbms_output.put_line('无数据记录');
end;

2、自定义异常

Oracle的自定义异常可以分为错误编号异常和业务逻辑异常两种。

2.1 错误编号异常

错误号异常是指在Oracle系统发生错误时,系统会显示错误号和相关描述信息的异常,虽然直接使用错误编号也可以完成异常处理,但错误编号较为抽象,不易于用户理解和记忆,对于这种异常,首先在PL/sql块的声明部分(DECLARE部分)使用EXCEPTION类型定义一个异常变量名,然后使用语句PRAGMA EXCEPTION_INIT为“错误编号”关联“这个异常变量名”,接下来就可以像对待系统预定义异常一样处理了。

【实例】定义错误编号“-00001”的异常变量,然后向dept表中插入一条能够“违反唯一约束条件”的记录,最后在exception代码体中输出异常提示信息。

declare
  primary_iterant exception;                       --定义一个异常变量
  pragma exception_init(primary_iterant,-00001);   --关联错误号和异常变量名
begin
  insert into dept values(10,'软件开发部','深圳');  --向dept表中插入一条与已有主键值重复的记录,以便引发异常
exception
  when primary_iterant then                        --若oracle捕获到的异常为-00001异常
    dbms_output.put_line('主键不允许重复!');       --输出异常描述信息
end;

2.2 业务逻辑异常

在实际的应用中,程序开发人员可以根据具体的业务罗规则自定义一个异常。这样,当用户操作违反业务逻辑规则时,就引发一个自定义异常,从而中断程序的正常执行并转到自定义的异常处理部分。

但无论是预定义异常,还是错误编号异常,都是由Oracle系统判断的错误,但业务逻辑异常是Oracle系统本身是无法知道的,这样就需要有一个引发异常的机制,引发业务逻辑异常通常使用RAISE语句来实现。当引发一个异常时,控制就会转到EXCEPTION异常处理部分执行异常处理语句。业务逻辑异常首先在DECLARE部分使用EXCEPTION类型声明一个异常变量,然后在BEGIN部分根据一定的义务逻辑规则执行RAISE语句(在RAISE关键字后面跟着异常变量名),最后在EXCEPTION部分编写异常处理语句。

【实例】自定义一个异常处理变量,在向dept表中插入数据时,若判断loc字段的值为null,则使用raise语句引发异常,并将程序的执行流程转入到EXCEPTION部分进行处理。
declare
  null_exception exception;                             --声明一个exception类型的异常变量
  dept_row dept%rowtype;                                --声明rowtype类型的变量dept_row,与dept表中一行的数据类型相同
begin
  dept_row.deptno := 66;                                --给部门编号变量赋值
  dept_row.dname := '公关部';                           --给部门名称变量赋值
  insert into dept 
  values(dept_row.deptno,dept_row.dname,dept_row.loc);  --向dept表中插入一条记录
  if dept_row.loc is null then                          --如果判断“loc”变量的值为null
    raise null_exception;                               --引发null异常,程序转入exception部分
  end if;
exception
  when null_exception then                              --当raise引发的异常是null_exception时
    dbms_output.put_line('loc字段的值不许为null');       --输出异常提示信息
  rollback;                                             --回滚插入的数据记录
end;
原文链接:https://www.f2er.com/oracle/209420.html

猜你在找的Oracle相关文章