• Oracle基础 PL-SQL编程基础(4) 异常处理


    异常处理:

    即使良好的PL-SQL程序也会遇到错误或者未预料的事件,一个优秀的程序都应该能够处理各种出错情况,尽可能的从错误中恢复。程序在运行时出现的错误成为异常。发生异常后,语句讲终止执行,PLSQL会立即将控制权交给PLSQL异常处理部分。Oracle中使用EXCEPTION来处理异常,一般有3种异常错误。

    有三种类型的异常错误:

        1. 预定义 ( Predefined )错误

       ORACLE预定义的异常情况大约有24个。对这种异常情况的处理,无需在程序中定义,由ORACLE自动将其引发。

        2. 非预定义 ( Predefined )错误

       即其他标准的ORACLE错误。对这种异常情况的处理,需要用户在程序中定义,然后由ORACLE自动将其引发。

        3. 用户定义(User_define) 错误

       程序执行过程中,出现编程人员认为的非正常情况。对这种异常情况的处理,需要用户在程序中定义,然后显式地在程序中将其引发。

     

    异常处理部分一般放在 PL/SQL 程序体的后半部:

    语法:

    EXCEPTION
       WHEN first_exception THEN  第一个异常处理的代码;
       WHEN second_exception THEN  第二个异常处理的代码
       WHEN OTHERS THEN  其他异常处理的代码
    END;

     

    1、预定义错误:

      由Oracle预先定义好的异常,Oracle中预定义的异常大约有24个。如下表所示。

    错误号

    异常错误信息名称

    说明

    ORA-0001

    Dup_val_on_index

    违反了唯一性限制

    ORA-0051

    Timeout-on-resource

    在等待资源时发生超时

    ORA-0061

    Transaction-backed-out

    由于发生死锁事务被撤消

    ORA-1001

    Invalid-CURSOR

    试图使用一个无效的游标

    ORA-1012

    Not-logged-on

    没有连接到ORACLE

    ORA-1017

    Login-denied

    无效的用户名/口令

    ORA-1403

    No_data_found

    SELECT INTO没有找到数据

    ORA-1422

    Too_many_rows

    SELECT INTO 返回多行

    ORA-1476

    Zero-divide

    试图被零除

    ORA-1722

    Invalid-NUMBER

    转换一个数字失败

    ORA-6500

    Storage-error

    内存不够引发的内部错误

    ORA-6501

    Program-error

    内部错误

    ORA-6502

    Value-error

    转换或截断错误

    ORA-6504

    Rowtype-mismatch

    宿主游标变量与 PL/SQL变量有不兼容行类型

    ORA-6511

    CURSOR-already-OPEN

    试图打开一个已处于打开状态的游标

    ORA-6530

    Access-INTO-null

    试图为null 对象的属性赋值

    ORA-6531

    Collection-is-null

    试图将Exists 以外的集合( collection)方法应用于一个null pl/sql 表上或varray上

    ORA-6532

    Subscript-outside-limit

    对嵌套或varray索引得引用超出声明范围以外

    ORA-6533

    Subscript-beyond-count

    对嵌套或varray 索引得引用大于集合中元素的个数.

    注意:预定义异常,首先是违背了 Oracle的规范,其次Oracle只为那20多个异常取了名字,如错误号"ORA-01043未找到数据"被命名为"NO_DATA_FOUND",这样在PLSQL中使用NO_DATA_FOUND来捕获处理就可以了。

    示例:

    DECLARE
      V_ID NUMBER;
    BEGIN
        SELECT ID INTO v_id FROM es_user WHERE 1=0; 
        DBMS_OUTPUT.put_line(v_id);
        EXCEPTION
          WHEN too_many_rows THEN
               DBMS_OUTPUT.put_line('无法将查询的多个值赋给变量');
          WHEN no_data_found THEN
               DBMS_OUTPUT.put_line('无法将空值付给变量');
          WHEN OTHERS THEN
               DBMS_OUTPUT.put_line('其他异常');
    END; 

    如果查询语句返回多个结果,则会too_many_rows中的异常处理代码,如果没有值返回,则执行no_data_found异常处理的代码。如果发生其他错误,则执行others中的异常处理代码

    2、非预定义错误

    非预定义异常指其他标准的Oracle错误,对于这话总异常处理的情况,需要用户在程序中定义,然后由Oracle自动将其引发。

    对于这类异常处理,首先必须对非定义的Oracle异常进行定义。步骤如下:

      (1)在PLSQL声明部分定义异常情况。

    DECLARE
      FK_EXCEPTION EXCEPTION;  --定义一个异常

      (2)将其定义好的异常与标准的Oracle异常联系起来,使用EXCEPTION_INIT语句:

      PRAGMA EXCEPTION_INIT(FK_EXCEPTION,-2291);  --2291为Oracle定义的错误号,也就是违反了外键约束

      (3)在PLSQL中的异常处理部分对异常做出相应的处理。(完整代码)

    DECLARE
      FK_EXCEPTION EXCEPTION;
        PRAGMA EXCEPTION_INIT(FK_EXCEPTION,-2291);     --2291为Oracle定义的错误号,也就是违反了外键约束
    BEGIN
        UPDATE ES_ORDER SET user_id = 100 WHERE ID=1;  --修改用户的ID为一个不存在的值,则会引发异常。
        EXCEPTION
            WHEN fk_exception THEN
                DBMS_OUTPUT.put_line('该用户不存在');
    END;

      非预定义异常同预定义异常一样,也是违背了Oracle的规范,但Oracle没有为这种异常取名字,如错误号"ORA-2291",没有名字,这样在PLSQL块的异常部分无法拨货,所以要预先定义异常变量。

    3、用户自定义错误

    程序执行过程中,出现了编程人员认为的非正常情况,对于这种异常情况,需要用户在程序中定义异常,然后显示的在程序中将其印发。用户自定义异常通过raise语句来触发。当引发这个异常,程序会专项EXCEPTION快处理异常。

    对于这种异常处理,步骤如下:

      (1)在声明部分声明异常

    DECLARE
      AGE_EXCEPTION EXCEPTION;  --声明一个异常

      (2)抛出异常信息

    IF v_age < 0 OR v_age > 100 THEN
            RAISE age_exception;
    END IF;

      (3)在PLSQL异常处理部分对异常情况作出相应的处理。

    EXCEPTION
        WHEN age_exception THEN
            DBMS_OUTPUT.put_line('年龄只能在0-100之间!');

    示例:(判断年龄是否在0-100之间)

    DECLARE
      V_AGE NUMBER := &AGE;
      AGE_EXCEPTION EXCEPTION;
    BEGIN
        IF v_age < 0 OR v_age > 100 THEN
            RAISE age_exception;
        END IF;
        EXCEPTION
            WHEN age_exception THEN
                DBMS_OUTPUT.put_line('年龄只能在0-100之间!');
    END;

    异常存储过程:

    除了以上3种异常处理,RAISE_APPLICATION_ERROR存储过程,可以重新定义异常错误消息,它为应用程序提供了一种与Oracle交互的方法。

    语法:

      RAISE_APPLICATION_ERROR(error_number,error_message);

      error_number:表示用户为异常指定的编号,该编号必须是介于-20000~-20999之间的负整数。

      error_message:表示用户为异常指定的消息文本。消息长度可长达2048字节,错误消息是与error_number关联的文本。

  • 相关阅读:
    zend framework多模块配置
    java解析xml的几种方式
    jdbc操作步骤和preparedStatment相比Statment的好处
    Android UI 之实现多级列表TreeView
    python小游戏实现代码
    【iOS知识学习】_UITableView简介
    根据指定电话号码得到通讯录上的姓名
    HDU 4705 Y
    C#实现的内存分页机制的一个实例
    【编程程序猿艺术】学习记录1:指针向左翻转法的旋转串
  • 原文地址:https://www.cnblogs.com/zhengcheng/p/4170699.html
Copyright © 2020-2023  润新知