zoukankan      html  css  js  c++  java
  • Oracle异常处理

    Oracle developer的异常处理机制
    Oracle developer的异常处理机制 Oracle developer以其快速的数据处理开发而闻名,其异常处理机制也是比较完善,不可小觑。
    1、 异常的优点 如果没有异常,在程序中,应当检查每个命令的成功还是失败,如 BEGIN SELECT ... -- check for ’no data found’ error SELECT ... -- check for ’no data found’ error SELECT ... -- check for ’no data found’ error 这种实现的方法缺点在于错误处理没有与正常处理分开,可读性差,使用异常,可以方便处理错误,而且异常处理程序与正常的事务逻辑分开,提高了可读性,如 BEGIN SELECT ... SELECT ... SELECT ... ... EXCEPTION WHEN NO_DATA_FOUND THEN -- catches all ’no data found’ errors 2、 异常的分类 有两种类型的异常,一种为内部异常,一种为用户自定义异常,内部异常是执行期间返回到PL/SQL块的ORACLE错误或由PL/SQL代码的某操作引起的错误,如除数为零或内存溢出的情况。用户自定义异常由开发者显示定义,在PL/SQL块中传递信息以控制对于应用的错误处理。 每当PL/SQL违背了ORACLE原则或超越了系统依赖的原则就会隐式的产生内部异常。因为每个ORACLE错误都有一个号码并且在PL/SQL中异常通过名字处理,ORACLE提供了预定义的内部异常。如SELECT INTO 语句不返回行时产生的ORACLE异常NO_DATA_FOUND。对于预定义异常,现将最常用的异常列举如下: exception oracle error sqlcode value condition no_data_found ora-01403 +100 select into 语句没有符合条件的记录返回 too_mang_rows ora-01422 -1422 select into 语句符合条件的记录有多条返回 dup_val_on_index ora-00001 -1 对于数据库表中的某一列,该列已经被限制为唯一索引,程序试图存储两个重复的值 value_error ora-06502 -6502 在转换字符类型,截取或长度受限时,会发生该异常,如一个字符分配给一个变量,而该变量声明的长度比该字符短,就会引发该异常 storage_error ora-06500 -6500 内存溢出 zero_divide ora-01476 -1476 除数为零 case_not_found ora-06592 -6530 对于选择case语句,没有与之相匹配的条件,同时,也没有else语句捕获其他的条件 cursor_already_open ora-06511 -6511 程序试图打开一个已经打开的游标 timeout_on_resource ora-00051 -51 系统在等待某一资源,时间超时 如果要处理未命名的内部异常,必须使用OTHERS异常处理器或PRAGMA EXCEPTION_INIT 。PRAGMA由编译器控制,或者是对于编译器的注释。PRAGMA在编译时处理,而不是在运行时处理。EXCEPTION_INIT告诉编译器将异常名与ORACLE错误码结合起来,这样可以通过名字引用任意的内部异常,并且可以通过名字为异常编写一适当的异常处理器。 在子程序中使用EXCEPTION_INIT的语法如下: PRAGMA EXCEPTION_INIT(exception_name, -Oracle_error_number); 在该语法中,异常名是声明的异常,下例是其用法: DECLARE deadlock_detected EXCEPTION; PRAGMA EXCEPTION_INIT(deadlock_detected, -60); BEGIN ... -- Some operation that causes an ORA-00060 error EXCEPTION WHEN deadlock_detected THEN -- handle the error END; 对于用户自定义异常,只能在PL/SQL块中的声明部分声明异常,异常的名字由EXCEPTION关键字引入: reserved_loaned Exception 产生异常后,控制传给了子程序的异常部分,将异常转向各自异常控制块,必须在代码中使用如下的结构处理错误: Exception When exception1 then Sequence of statements; When exception2 then Sequence of statements; When others then 3、异常的抛出 由三种方式抛出异常 1. 通过PL/SQL运行时引擎 2. 使用RAISE语句 3. 调用RAISE_APPLICATION_ERROR存储过程  当数据库或PL/SQL在运行时发生错误时,一个异常被PL/SQL运行时引擎自动抛出。异常也可以通过RAISE语句抛出   RAISE exception_name;   显式抛出异常是程序员处理声明的异常的习惯用法,但RAISE不限于声明了的异常,它可以抛出任何任何异常。例如,你希望用TIMEOUT_ON_RESOURCE错误检测新的运行时异常处理器,你只需简单的在程序中使用下面的语句:   RAISE TIMEOUT_ON_RESOUCE; 比如下面一个订单输入的例子,若当订单小于库存数量,则抛出异常,并且捕获该异常,处理异常 DECLARE inventory_too_low EXCEPTION; ---其他声明语句 BEGIN IF order_rec.qty>inventory_rec.qty THEN RAISE inventory_too_low; END IF EXCEPTION WHEN inventory_too_low THEN order_rec.staus:='backordered'; END;
    RAISE_APPLICATION_ERROR内建函数用于抛出一个异常并给异常赋予一个错误号以及错误信息。自定义异常的缺省错误号是+1,缺省信息是User_Defined_Exception。RAISE_APPLICATION_ERROR函数能够在pl/sql程序块的执行部分和异常部分调用,显式抛出带特殊错误号的命名异常。 Raise_application_error(error_number,message[,true,false]))   错误号的范围是-20,000到-20,999。错误信息是文本字符串,最多为2048字节。TRUE和FALSE表示是添加(TRUE)进错误堆(ERROR STACK)还是覆盖(overwrite)错误堆(FALSE)。缺省情况下是FALSE。 如下代码所示: IF product_not_found THEN   RAISE_APPLICATION_ERROR(-20123,'Invald product code' TRUE); END IF; 4、异常的处理 PL/SQL程序块的异常部分包含了程序处理错误的代码,当异常被抛出时,一个异常陷阱就自动发生,程序控制离开执行部分转入异常部分,一旦程序进入异常部分就不能再回到同一块的执行部分。下面是异常部分的一般语法: EXCEPTION  WHEN exception_name THEN   Code for handing exception_name  [WHEN another_exception THEN   Code for handing another_exception]  [WHEN others THEN   code for handing any other exception.] 用户必须在独立的WHEN子串中为每个异常设计异常处理代码,WHEN OTHERS子串必须放置在最后面作为缺省处理器处理没有显式处理的异常。当异常发生时,控制转到异常部分,ORACLE查找当前异常相应的WHEN..THEN语句,捕捉异常,THEN之后的代码被执行,如果错误陷阱代码只是退出相应的嵌套块,那么程序将继续执行内部块END后面的语句。如果没有找到相应的异常陷阱,那么将执行WHEN OTHERS。在异常部分WHEN 子串没有数量限制。 EXCEPTION  WHEN inventory_too_low THEN   order_rec.staus:='backordered';   replenish_inventory(inventory_nbr=>   inventory_rec.sku,min_amount=>order_rec.qty-inventory_rec.qty);  WHEN discontinued_item THEN   --code for discontinued_item processing  WHEN zero_divide THEN   --code for zero_divide  WHEN OTHERS THEN   --code for any other exception END; 当异常抛出后,控制无条件转到异常部分,这就意味着控制不能回到异常发生的位置,当异常被处理和解决后,控制返回到上一层执行部分的下一条语句。 BEGIN   DECLARE   bad_credit exception;   BEGIN   RAISE bad_credit;    --发生异常,控制转向;   EXCEPTION   WHEN bad_credit THEN    dbms_output.put_line('bad_credit');   END;   --bad_credit异常处理后,控制转到这里  EXCEPTION   WHEN OTHERS THEN    --控制不会从bad_credit异常转到这里    --因为bad_credit已被处理 END; 当异常发生时,在块的内部没有该异常处理器时,控制将转到或传播到上一层块的异常处理部分。 BEGIN   DECLARE ---内部块开始   bad_credit exception;   BEGIN   RAISE bad_credit;    --发生异常,控制转向;   EXCEPTION   WHEN ZERO_DIVIDE THEN --不能处理bad_credite异常    dbms_output.put_line('divide by zero error');   END --结束内部块    --控制不能到达这里,因为异常没有解决;    --异常部分   EXCEPTION   WHEN OTHERS THEN    --由于bad_credit没有解决,控制将转到这里 END; 5、异常的传播 没有处理的异常将沿检测异常调用程序传播到外面,当异常被处理并解决或到达程序最外层传播停止。在声明部分抛出的异常将控制转到上一层的异常部分。 BEGIN executable statements BEGIN today DATE:='SYADATE'; --ERRROR BEGIN --内部块开始 dbms_output.put_line('this line will not execute'); EXCEPTION WHEN OTHERS THEN --异常不会在这里处理 END;--内部块结束 EXCEPTION WHEN OTHERS THEN 处理异常 END 执行部分抛出的异常将首先传递到同一块的异常部分,如果在同一块的异常部分没有处理这个异常的处理器,那么异常将会传播到上一层的异常部分中,一直到最外层。   在异常部分抛出的异常将控制转到上一层的异常部分。   另外错误报告函数SQLCODE和SQLERRM在OTHERS处理器中特别有用,因为它们返回ORACLE错误代码和消息。如下例所示: declare err_num NUMBER; err_msg VARCHAR2(100); BEGIN ... EXCEPTION WHEN OTHERS THEN err_num := SQLCODE; err_msg := SUBSTR(SQLERRM, 1, 100); INSERT INTO errors VALUES (err_num, err_msg); END;

  • 相关阅读:
    jQuery 语法
    jQuery 简介
    把数据存储到 XML 文件
    XML 注意事项
    XML DOM (Document Object Model) 定义了访问和操作 XML 文档的标准方法。
    通过 PHP 生成 XML
    XML 命名空间(XML Namespaces)
    XML to HTML
    XMLHttpRequest 对象
    使用 XSLT 显示 XML
  • 原文地址:https://www.cnblogs.com/gaolonglong/p/2240909.html
Copyright © 2011-2022 走看看