异常处理:

即使良好的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关联的文本。

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

  1. Oracle数据库编程:PL/SQL编程基础

    2.PL/SQL编程基础: PL/SQL块:        declare        定义部分        begin        执行部分        exception        异 ...

  2. 【PL/SQL编程基础】

    [PL/SQL编程基础]语法: declare 声明部分,例如定义变量.常量.游标 begin 程序编写,SQL语句 exception 处理异常 end: / 正斜杠表示执行程序快范例 -- Cre ...

  3. Oracle Pl/SQL编程基础

    Pl/SQL简介 提高应用程序的运行性能, 提供模块化的程序设计, 自定义标示符, 具有过程语言控制结构, 良好的兼容性, 处理运行错误. Pl/SQL语言基础 sql是关系数据库的基本操作语言. s ...

  4. PL/SQL编程基础(五):异常处理(EXCEPTION)

    异常处理 异常产生所带来的问题: 使用EXCEPTION程序块进行异常处理: 实现用户自定义异常. 使用异常可以保证在程序中出现运行时异常时程序可以正常的执行完毕: 用户可以使用自定义异常进行操作. ...

  5. PL/SQL编程基础(三):数据类型划分

    数据类型划分 在Oracle之中所提供的数据类型,一共分为四类: 标量类型(SCALAR,或称基本数据类型) 用于保存单个值,例如:字符串.数字.日期.布尔: 标量类型只是作为单一类型的数据存在,有的 ...

  6. Oracle之PL/SQL编程

    PL/SQL(Procedural Language/SQL,过程语言/SQL) 是结合了Oracel过程语言和结构化查询语言(SQL)的一种扩展语言. 优点: (1)PL/SQL具有编程语言的特点, ...

  7. oracle PL/SQL编程基础知识

    在oracle中使用pl/sql来扩展SQL的功能,使得SQL能够更加的灵活,功能更加强大,效率更高.pl/sql让sql也能执行判断,循环等操作.主要记录一下pl/sql的基本语法和基本条件判断语句 ...

  8. Oracle PL/SQL 编程基础 实例

    create table mytest(name varchar(20),password varchar(30)); create or replace procedure sp_pro2 is  ...

  9. PL/SQL编程基础(一):PL/SQL语法简介(匿名PL/SQL块)

    PL/SQL PL/SQL是Oracle在关系数据库结构化查询语言SQL基础上扩展得到的一种过程化查询语言. SQL与编程语言之间的不同在于,SQL没有变量,SQL没有流程控制(分支,循环).而PL/ ...

  10. PL/SQL编程基础——PL/SQL简介

    课程教师:李兴华 课程学习者:阳光罗诺 日期:2018-07-28 知识点: 1. 了解PL/SQL的主要特点 2. 掌握PL/SQL块的基本结构 PL/SQL PL/SQL是Oracle在关系数据库 ...

随机推荐

  1. ZOJ 3596Digit Number(BFS+DP)

    一道比较不错的BFS+DP题目 题意很简单,就是问一个刚好包含m(m<=10)个不同数字的n的最小倍数. 很明显如果直接枚举每一位是什么这样的话显然复杂度是没有上限的,所以需要找到一个状态表示方 ...

  2. LeetCode 刷题记录

    写在前面:因为要准备面试,开始了在[LeetCode]上刷题的历程.LeetCode上一共有大约150道题目,本文记录我在<http://oj.leetcode.com>上AC的所有题目, ...

  3. react native 网络get请求方式参数不可为undefined或null

    react native 网络get请求方式参数不可为undefined(为空的话默认变为)或null 错误写法: export function addToCartAction(isRefreshi ...

  4. springMVC使用注解方式进行页面跳转

    <!--控制层-->package cn.org.spartacus.spring; import org.springframework.beans.factory.annotation ...

  5. C:指针

    指针 指针数组   参考1   参考2  参考3  参考4 1.指针 也是一种变量.指针内部存的是一块内存的地址. //指针: 通常我们说的指针其实是指针变量,相比于其他基本数据类型的变量不同,它存储 ...

  6. 无责任Windows Azure SDK .NET开发入门篇三[使用Azure AD 管理用户信息--3.4 Edit修改用户信息]

    3.4 Edit修改用户信息 我们用FormCollection简化了表单提交,非常方便的进行用户信息修改. [HttpPost, Authorize] public async Task<Ac ...

  7. Js 基本数据类型、引用数据类型

    数据类型 1.   ECMAScript变量包含两种不同类型的值:基本类型值.引用类型值: 2.   基本类型值:指的是保存在栈内存中的简单数据段: 3.   引用类型值:指的是那些保存在堆内存中的对 ...

  8. TT付款方式、前TT和后TT、LC信用证+TT付款方式

    TT付款方式是以外汇现金方式结算,由您的客户将款项汇至贵公司指定的外汇银行账号内,可以要求货到后一定期限内汇款. .T/T属于商业信用,也就是说付款的最终决定权在于客户.T/T分预付,即期和远期.现在 ...

  9. [Angular2 Router] Programmatic Router Navigation via the Router API - Relative And Absolute Router Navigation

    In this tutorial we are going to learn how to navigate programmatically (or imperatively) by using t ...

  10. 怎样通过Java程序提交yarn的mapreduce计算任务

    因为项目需求,须要通过Java程序提交Yarn的MapReduce的计算任务.与一般的通过Jar包提交MapReduce任务不同,通过程序提交MapReduce任务须要有点小变动.详见下面代码. 下面 ...