Oracle--plsql异常处理

什么是异常 ?
Oracle 中出现错误的情形通常分为编译时错误( compile-timeerror )和运行时错误 (run-time error) ,异常是在 PL/SQL 执行过程中出现的警告或错误。

异常是如何触发的?
发生了一个 Oracle 错误时
使用RAISE语句显式触发

如何处理异常?
用处理机截获
在调用环境中传播异常

两种触发异常方法:

发生了 Oracle 错误,就会自动触发相关的异常。

可以在块中使用RAISE语句显式的触发异常。被触发的异常可以是预定义的异常,也可以是自定义的异常。




截获异常

如果在块的执行部分异常被触发,当前的块就会转去执行异常处理部分的相应异常处理机。如果PL/SQL成功处理了异常,就不会把异常传播给外部块或环境,从而,PL/SQL块正常结束。

异常的传播

如果在块的执行部分异常被触发, 然而没有相应的异常处理机,块就会异常终止,而将异常传递给调用环境。

错误引发异常,每当引发异常时,都将控制权传递给异常处理程序,异常处理程序处理异常.


捕获异常:

EXCEPTION WHEN exception1 [OR exception2 . . .] THEN statement1; statement2; . . . [WHEN exception3 [OR exception4 . . .] THEN statement1; statement2; . . .] [WHEN OTHERS THEN statement1; statement2; . . .]


在异常部分 WHEN 子句没有数量限制
WHEN OTHERS 是最后一个子句
异常处理部分从关键字 EXCEPTION 开始
当异常抛出后,控制无条件转到异常处理部分
在离开块之前只能执行一种异常处理

预定义异常:

预定义异常是由 Oracle 为常见错误预先定义的,不需要显式声明。

在相应的异常处理例程中引用错误的标准名来截获一个Oracle 服务器预定义错误。


例子:

DECLARE v_sal emp.sal%type; BEGIN SELECT sal INTO v_sal FROM emp WHERE empno=999; EXCEPTION WHEN NO_DATA_FOUND then dbms_output.put_line('没有查到数据'); WHEN others then dbms_output.put_line('其它异常'); END;

要截获Oracle服务器没有预定义的错误,需先声明这个错误或者使用OTHERS处理机。 



非预定义异常:

1.  在声明部分声明异常名。

    语法:

    exception      EXCEPTION;

    其中:  exception  异常名

2.  使用PRAGMAEXCEPTION_INIT语句将异常处理名字和Oracle的错误代码关联起来.

   语法:

   PRAGMA   EXCEPTION_INIT ( exception, error_number ) ;

    其中:  exception  先前声明的异常名

   error_number  标准Oracle 错误代码

3.  在相应的异常处理例程中引用已声明的异常。


关键字 PRAGMA (伪指令pseudoinstructions)表示语句是一个编译指令,在执行PL/SQL块时并不处理该语句。在PL/SQL块中,一个编译指令EXCEPTION_INIT告诉编译器将一个异常处理的名字和一个Oracle错误代码联系起来。

DECLARE e_emp_cons EXCEPTION; PRAGMA EXCEPTION_INIT(e_emp_cons,-00001); BEGIN INSERT INTO emp SELECT * FROM emp; EXCEPTION WHEN e_emp_cons THEN dbms_output.put_line('违反唯一性约束'); END;
捕获异常的函数:

SQLCODE

  返回Oracle的错误代码

SQLERRM

  返回和错误值相关联的信息

SQLCODE值  说明

  0      没有异常   

  100      NO_DATA_FOUND异常

  负数      其它 Oracle 错误号


自定义异常:

在PL/SQL块的声明部分声明。

使用RAISE语句显式地发布 。


异常的传递;

当子块自己处理异常时,它可以正常终止,并且在子块的END语句之后可以立即将控制交给外部块。

然而,如果 PL/SQL出现了异常,但当前块中没有针对该异常的处理机,就会寻找外部块中有没有处理机,如果所有的外部块都不能处理这个异常,则就会在宿主环境中出现未经处理的异常。

当把异常传播给外部块,则当前块中的等待执行代码都不再被执行。

这种方法的优点就是内部块仅处理自己特有的错误,而将一般的异常处理留给外部块。

Raise_Application_Error过程
用于创建用户定义的错误消息的过程
向用户返回错误,并且其返回格式和其它Oracle错误的格式相同
既可以在可执行部分中使用,也可以在异常部分中使用

  Raise_Application_Error(error_number,message);

错误编号必须介于 –20000 –20999 之间
错误消息的长度可长达 2048 个字节

利用过程 RAISE_APPLICATION_ERRO返回一个非标准的错误代码和错误消息,从而可以和预定义异常进行交互。使用RAISE_APPLICATION_ERROR就可以向应用程序报告错误消息,并且避免了返回没有处理过的异常。

执行区域: BEGIN … delete from emp where demtno=10; if SQL%NOTFOUND then Raise_Application_Error(-20202, ’this is not a valid department’); end if; … 异常区域: EXCEPTION when NO_DATA_FOUND then Raise_Application_Error(-20202, ’this is not a valid department’); END;


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值