pl/sql 中关于exception的学习笔记

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

转载于:https://www.cnblogs.com/cuihongyu3503319/archive/2007/11/19/964681.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/300574.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一文读懂 .NET 中的高性能队列 Channel

介绍System.Threading.Channels 是.NET Core 3.0 后推出的新的集合类型, 具有异步API,高性能,线程安全等特点,它可以用来做消息队列,进行数据的生产和消费, 公开的 Writer 和 Reader api对应消息的生产者和消费者,也让Channel更加…

java字符数组初始化_Java 字符串(一)字符串初始化

一、String类概述1、概述java.lang.String类代表字符串。Java程序中所有的字符串文字(例如 "abc" )都可以被看作是实现此类的实例。String 是引用数据类型,不是基本数据类型。类String 中包括用于检查各个字符串的方法,比如用于比较字符串&…

一晚啪了5只喵,累到在医院打点滴,这中国喵把英国人看傻了 | 今日最佳

世界只有3.14 % 的人关注了青少年数学之旅最近,一只叫xiaopi的中国猫在英国红了!好多媒体都报道了它…“猫咪一夜连XX 5只母喵后,累到挂点滴”《LADbible》,《Mirror》都可以看到它疲惫的小脸蛋…在《每日邮报》,xiaop…

放假的第二天

嗯...今天是放假的第二天.感觉昨天过了好漫长的一天哦,长得都有好几年了....昨天早上和某军去爬山,蛮惊喜的实话的说,可是快到山顶的时候罗打电话给某军说高二化学(2)要照相,某军却骗她说他正和一男孩儿爬山,男孩儿.....我....纠结.....后来过了好久,我们终于从山上下来了,赶到…

Locations Section of OpenCascade BRep

Locations Section of OpenCascade BRep eryar163.com 摘要Abstract:本文结合OpenCascade的BRep格式描述文档和源程序,对BRep格式进行分析,详细说明BRep的数据组织形式。本文主要通过对BRep文件中的Locations部分的读写代码进行分析&#xff…

2007武汉.NET俱乐部沙龙-VS2008、WPF、Silverlight

即将进入2008年,激动人心的一年。微软也将活跃起来,讨论微软技术发展的最新趋势,产品与解决方案的商业价值,新技术对未来行业的影响,使您以饱满的激情碰撞2008!与此同时,微软又带给开发人员什么…

java long to float_为什么Java中long可以自动转换成float

Java中,long型是64位的,float型是32位的。为什么long型可以自动转float型呢?这里就涉及到浮点数在内存中的存储问题了。对于byte,short,int,long四个整数类型而言,它们在内存中无一例外都是直接换算成二进…

C# 枚举(Enum)

在数学和计算机科学理论中,一个集的枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数。这两种类型经常(但不总是)重叠。[1] 是一个被命名的整型常数的集合,枚举在日常生活中很常见&#xff0c…

孙悟空都服输!波士顿动力最新逆天机器人视频,翻筋斗连拿大顶!

全世界只有3.14 %的人关注了青少年数学之旅刚刚,波士顿动力公司在YouTube发布了两段真正震撼的新视频:双足人形机器人Atlas展示倒立、360度翻跟头、旋转的跑酷Demo:More Parkour Atlas。四足机器人Spot的商业化广告宣传片:Spot La…

痛并快乐着

看到访问量不断增加,而且访问过的人数已经超过500人(注意不是浏览次数,而是不同的人数),真有成就感。与此同时,申请网易联盟再次失败,决定好好写我自己的blog,不再去管他什么狗屁联盟…

C#实例:datagridview单元格合并

这是替C#微信交流群群友做的一个小实例,目的就是在datagridview选择对应行以后,点击button后获取对应行的ip,并执行相应的操作,其实我觉得这样的话button没必要非放置到datagridview里面的!但是为了满足群友的需求&…

NO.106 需求的状态、研发阶段及注意事项。

为什么80%的码农都做不了架构师?>>> 禅道项目管理软件设计的需求有两个字段来跟踪它的变化,一个是需求的状态字段,一个是需求的研发阶段字段,下面来看下这两个字段。 一、需求的状态 需求状态(status)字段&#xff0c…

java实例化泛型_Java让泛型实例化的方法

泛型对象可以实例化吗?不可以,T tnew T()是不可以的,编译器会报错。由于泛型擦除,编译器在编译时无法确定泛型所对应的真实类型解决方法使用反射新建实例Type superclass getClass().getGenericSuperclass();ParameterizedType p…

几种人类设计的永动机,最后一个彻底服了!| 今日最佳

全世界只有3.14 %的人关注了青少年数学之旅众所周知,永动机是违反当前客观科学规律的概念,是永远不能够被制造出来的。下面这些都是人们根据不同原理设计出来的,看一看有什么神奇之处,最后一个是亮点!▲达芬奇设计的永…

vista 中php4, php5 共存

由于有些开源PHP产品需要PHP4,因为不得不安装这个版本,如OSC2.1;而有些开源产品则使用PHP5,如wikipedia,因此为了同时开发 PHP4或PHP5的软件,则需要同时安装这两个版本的东西。 安装PHP4使用IIS的具体操作请…

剖析WPF依赖属性

这节来讲一下WPF中的依赖属性 (Dependency Property)。【了解属性和字段】我们知道,属性是面向对象语言中用来封装字段的外衣,它像是字段对外界的桥梁,我们可以通过属性来验证数据的合法性或控制对外的访问性等等。每个属性的背后都有其对应的…

Spring与SpringMVC集成出现的问题

这几天在学习SpringMVC,在与Spring集成时,出现了两个小问题,记录下来,提醒自己,同时如果大家遇到同样问题,能够帮助大家的话,那我就感到幸哉了!1.java.lang.NullPointerExceptionSEV…

java drawline_Java Graphics.drawLine方法代码示例

import javax.microedition.lcdui.Graphics; //导入方法依赖的package包/类public void draw(Graphics g) {g.setColor(255, 255, 255);g.fillRect(0, 0, getWidth(), getHeight());g.setColor(200, 200, 200);int baseLineY;if (signal.baseLineY() > 0) {baseLineY (int)…

Active Directory的用户属性说明

Active Directory中User对象属性User Object User Interface Mapping The following tables identify the property pages supplied by the Active Directory Users and Computers snap-in. Each table identifies the user interface elements of the property page and the A…

柳传志与马云绸缪宏观经济“冬天影子”

春江水暖鸭先知。尽管认同中国经济的繁荣将继续保持10~20年,中国商界的领军者和经济学家上周六还是提醒企业必须警惕可能到来的调整。 “我为什么上市?一个很重要的原因,是我在准备‘过冬’。”12月8日,在“2007(第六届)中国企业领…