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关联的文本。

时间: 2024-10-24 02:03:37

PL-SQL编程基础(4) 异常处理的相关文章

【PL/SQL编程基础】

[PL/SQL编程基础]语法: declare 声明部分,例如定义变量.常量.游标 begin 程序编写,SQL语句 exception 处理异常 end: / 正斜杠表示执行程序快范例 -- Created on 2016/8/22 by VITAS declare 定义变量 v_num number; v_eno number; v_ename varchar2(10); begin v_num:=234; v_eno:=&empno; 接收输入变量 select ename into v_

Oracle PL/SQL 编程基础 实例

create table mytest(name varchar(20),password varchar(30)); create or replace procedure sp_pro2 is begin insert into mytest values('fc','123'); end; 查看错误信息 show error 如何调用该过程: 1, exec 过程名 (参数,..) 2.  call 过程名 (参数  ) set server output on begin dbms_ou

Oracle PL/SQL 编程基础 实例 2

if  循环  控制语句 if--then        endif if----then ----else   endif if-----then --elsif then ----else     endif --编写一个过程,可以 输入一个雇员名,如果该雇员的工资低于2000就给他增加10% create   or replace procedure  sp_pro6(spName varchar2) is v_sal  emp.sal %type; begin select sal in

pl/sql编程基础

PL/SQL 1.过程.函数.触发器是pl/sql编写的 2.过程.函数.触发器是存放在oracle数据库中的 3.pl/sql是非常强大的过程化语言 4.过程.函数.触发器可以在java程序中调用 pl/sql编写能节省一点时间就是提高了性能(量大),java直接调用数据库存放的过程,解析时间就节省下来了,提高了性能 模块化的设计思想----->存储过程 网络传输(java程序中编写的sql语言),直接调用数据库的过程节省了传输量 提高安全性(存储过程避免了数据库信息的泄漏) 缺点: 移植性不

PL/SQL 编程(一)基础,变量,分支,循环,异常

SQL和PL/SQL: SQL 结构化查询语言(Structural Query Language),是用来访问和操作关系型数据库的一种标准通用语言,属于第四代语言(4GL).可以方便的调用相应语句来去的结果,特点是非过程化,使用的时候不用指明执行的具体方法,不用关注实现的细节,但是某些情况下满足不了复杂业务流程的需求. PL/SQL是 Procedure Language & Structured Query Language 的缩写.属于第三代语言(3GL),是一种过程化语言.PL/SQL是

[顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功)

原文:[顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功) [顶]ORACLE PL/SQL编程详解之二: PL/SQL块结构和组成元素(为山九仞,岂一日之功) 继上四篇:ORACLE PL/SQL编程之八:把触发器说透                ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!)                [推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到) [推荐]

[推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆)

原文:[推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆) [推荐]ORACLE PL/SQL编程详解之三: PL/SQL流程控制语句(不给规则,不成方圆) ——通过知识共享树立个人品牌. 继上五篇: [顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功) [推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到) [推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼.百战不

[推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下)

原文:[推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下) [推荐]ORACLE PL/SQL编程详解之一: PL/SQL 程序设计简介(千里之行,始于足下) ——通过知识共享树立个人品牌. 继上六篇: [顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功) [推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆) [推荐]ORACLE PL/SQL编程之四:把游标说透(

ORACLE PL/SQL编程详解

ORACLE PL/SQL编程详解 编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设计语言,该语言专门用于在各种环境下对ORACLE数据库进行访问.由于该语言集成于数据库服务器中,所以PL/SQL代码可以对数据进行快速高效的处理.除此之外,可以在ORACLE数据库的某些客户端工具中,使用PL/SQL语言也是该语言的一个特点.本章的主要内容是讨论引入PL/SQL语言的必要性和该语言的

ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!)

原文:ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!) ORACLE PL/SQL编程之六: 把过程与函数说透(穷追猛打,把根儿都拔起!)   继上篇:ORACLE PL/SQL编程之八:把触发器说透 得到了大家的强力支持,感谢.接下来再下猛药,介绍下一篇,大家一定要支持与推荐呀~!我也才有动力写后面的.   本篇主要内容如下: 6.1 引言 6.2 创建函数 6.3 存储过程 6.3.1 创建过程 6.3.2 调用存储过程 6.3.3 AUTHID 6.3.4