Oracle数据库之PL/SQL异常处理
Oracle数据库之PL/SQL异常处理
异常指的是在程序运行过程中发生的异常事件,通常是由硬件问题或者程序设计问题所导致的。
PL/SQL程序设计过程中,即使是写得最好的程序也可能会遇到错误或未预料到的事件。一个健壮的程序都应该能够正确处理各种异常情况,并尽可能从中恢复。
1. 异常处理
异常处理是用来处理正常执行过程中未预料的事件。PL/SQL程序块一旦产生异常而没有指出如何处理时,程序就会自动终止整个程序运行。
PL/SQL编程过程中,有三种类型的异常:
1.预定义异常
对这种异常情况的处理,无需在程序中定义,当PL/SQL程序违反Oracle规则或超越系统限制时隐式引发。
2.非预定义异常
其他标准的Oracle错误。对这种异常情况的处理,需要用户在程序中定义,然后由Oracle自动将其引发。
3.用户定义异常
程序执行过程中,出现编程人员认为的非正常情况。对这种异常情况的处理,需要用户在程序中定义,然后显式地在程序中将其引发。
异常处理通常放在PL/SQL程序的后部,语法结构为:
EXCEPTION
WHEN { exception [ OR exception ]... | OTHERS }
THEN statement [ statement ]...
2. 预定义的异常处理
常见预定义异常:
| 错误号 | 异常名称 | 说明 | 
|---|---|---|
| ORA-00001 | DUP_VAL_ON_INDEX | 重复索引值,违反了唯一性限制,当在唯一索引所对应的列上键入重复值时触发 | 
| ORA-01001 | INVALID_CURSOR | 试图使用一个无效的游标 | 
| ORA-01012 | NOT_LOGGED_ON | 没有连接到ORACLE | 
| ORA-01017 | LOGIN_DENIED | 无效的用户名/口令 | 
| ORA-01403 | NO_DATA_FOUND | 没有找到数据时触发 | 
| ORA-01422 | TOO_MANY_ROWS | 返回多行 | 
| ORA-01722 | INVALID_NUMBER | 转换为数字失败时触发 | 
| ORA-06511 | CURSOR_ALREADY_OPEN | 试图打开一个已处于打开状态的游标 | 
| ORA-06592 | CASE_NOT_FOUND | 当case条件都不满足时触发 | 
更多预定义异常见:http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/errors.htm#LNPLS00703
对预定义异常的处理,只需在PL/SQL块的异常处理部分,直接引用相应的异常情况名,并对其完成相应的异常错误处理即可。
示例1:
DECLARE
stock_price NUMBER := 9.73;
net_earnings NUMBER := 0;
pe_ratio NUMBER;
BEGIN
pe_ratio := stock_price / net_earnings;
DBMS_OUTPUT.PUT_LINE('运算结果 = ' || pe_ratio);
EXCEPTION
WHEN ZERO_DIVIDE THEN
DBMS_OUTPUT.PUT_LINE('/ by zero');
pe_ratio := NULL;
END;
运行结果:
/ by zero
为避免除0异常,可以采用如下示例2方式解决:
示例2:
DECLARE
stock_price NUMBER := 9.73;
net_earnings NUMBER := 0;
pe_ratio NUMBER;
BEGIN
pe_ratio :=
CASE net_earnings
WHEN 0 THEN NULL
ELSE stock_price / net_earnings
END;
END;
示例3:
DECLARE
default_number NUMBER := 0;
BEGIN
INSERT INTO t VALUES(TO_NUMBER('100.00', '9G999'));
EXCEPTION
WHEN INVALID_NUMBER THEN
DBMS_OUTPUT.PUT_LINE('使用默认值替换非法数字');
INSERT INTO t VALUES(default_number);
END;
运行结果:
使用默认值替换非法数字
3. 非预定义的异常处理
非预定义异常有错误号没有名字,处理的办法是:自己定义一个名字,绑定到错误号,捕获错误名。处理这类异常,首先必须对非预定义的Oracle异常进行定义。
如:
myexcp EXCEPTION;
然后使用EXCEPTION_INIT语句与标准的ORACLE错误联系起来,如:
PRAGMA EXCEPTION_INIT(myexcp,-02292);
说明:ORA-02292是违反完整性约束的错误代码。
示例:
DECLARE
myexcp EXCEPTION;
PRAGMA EXCEPTION_INIT(myexcp,-02292);
dno scott.emp.deptno%TYPE;
BEGIN
dno := &dept_no;
DELETE FROM scott.dept WHERE deptno=dno;
EXCEPTION
WHEN myexcp THEN
DELETE FROM scott.emp WHERE deptno=dno;
DELETE FROM scott.dept WHERE deptno=dno;
END;
4. 用户定义异常处理
我们可以在任何PL/SQL匿名块,子程序或包的声明部分声明自己的异常。用户定义的异常是通过使用RAISE语句显式触发的。
一般用户定义异常的处理流程为:定义异常->抛出异常->捕获及处理异常。
示例:
DECLARE
invalidCATEGORY EXCEPTION; -- 定义异常
category VARCHAR2(10);
BEGIN
category := '&Category';
IF category NOT IN ('附件','顶盖','备件') THEN
RAISE invalidCATEGORY; -- 抛出异常
ELSE
DBMS_OUTPUT.PUT_LINE('您输入的类别是'|| category);
END IF;
EXCEPTION
WHEN invalidCATEGORY THEN -- 捕获及处理异常
DBMS_OUTPUT.PUT_LINE('无法识别该类别');
END;
我们可以调用RAISE_APPLICATION_ERROR过程引发并传播应用程序异常,这为应用程序提供了一种与ORACLE交互的方法。
RAISE_APPLICATION_ERROR过程可用于创建用户定义的错误信息,可以在可执行部分和异常处理部分使用,错误编号必须介于–20000 和–20999之间,错误消息的长度可长达2048个字节。
RAISE_APPLICATION_ERROR过程语法:
RAISE_APPLICATION_ERROR (error_code, message[, {TRUE | FALSE}]);
如果指定TRUE,PL/SQL把ERROR_CODE上的错误信息添加到堆栈的顶部。指定FALSE,PL/SQL替换ERROR_CODE错误堆栈,默认值为FALSE。
示例1:
DECLARE
empno employees.employee_id%TYPE;
no_such_row EXCEPTION;
BEGIN
empno := &empno;
UPDATE employees SET salary = salary+100 WHERE id = empno;
IF SQL%NOTFOUND THEN
RAISE no_such_row;
END IF;
EXCEPTION
WHEN no_such_row THEN
RAISE_APPLICATION_ERROR(-20001, '没有待修改的行');
END;
示例2:
BEGIN
UPDATE emp SET deptno=80 WHERE empno=1111;
IF SQL%NOTFOUND THEN
RAISE_APPLICATION_ERROR(-20001,'该雇员不存在!');
END IF;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(SQLCODE||'-->'||SQLERRM);
END;
SQLCODE用于取得Oracle错误号。
SQLERRM则用于取得与之相关的错误消息。
Oracle数据库之PL/SQL异常处理的更多相关文章
- Oracle数据库之PL/SQL过程与函数
		
Oracle数据库之PL/SQL过程与函数 PL/SQL块分为匿名块与命名块,命名块又包含子程序.包和触发器. 过程和函数统称为PL/SQL子程序,我们可以将商业逻辑.企业规则写成过程或函数保存到数据 ...
 - Oracle数据库之PL/SQL触发器
		
Oracle数据库之PL/SQL触发器 1. 介绍 触发器(trigger)是数据库提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程,它的执行不是由程序调用,也不是 ...
 - Oracle数据库之PL/SQL包
		
Oracle数据库之PL/SQL包 1. 简介 包(PACKAGE)是一种数据对象,它是一组相关过程.函数.变量.常量和游标等PL/SQL程序设计元素的组合,作为一个完整的单元存储在数据库中,用名称来 ...
 - Oracle数据库之PL/SQL流程控制语句
		
Oracle数据库之PL/SQL流程控制语句 在任何计算机编程语言(如C,Java,C#等)都有各种流程控制语句,同样,在PL/SQL中也存在这样的流程控制结构. 几种常见的流程控制结构: 一.条件结 ...
 - Oracle数据库之PL/SQL程序设计简介
		
PL/SQL程序设计简介 一.什么是PL/SQL? PL/SQL是 Procedure Language & Structured Query Language 的缩写. ORACLE的SQL ...
 - oracle数据库之PL/SQL 块结构和组成元素
		
一.PL/SQL 块 (一)PL/SQL 程序由三个块组成,即声明部分.执行部分.异常处理部分 PL/SQL 块的结构如下: 1.DECLARE /* 声明部分: 在此声明 PL/SQL 用到的变量, ...
 - Oracle数据库之PL/SQL程序设计基础
		
PL/SQL程序设计基础 一.PL/SQL块结构 前边我们已经介绍了PL/SQL块的结构,再来回顾一下: DECLARE /* * 声明部分——定义常量.变量.复杂数据类型.游标.用户自定义异常 */ ...
 - Oracle数据库之PL/SQL程序基础设计
		
一.PL/SQL块结构 前边我们已经介绍了PL/SQL块的结构,再来回顾一下: DECLARE /* * 声明部分——定义常量.变量.复杂数据类型.游标.用户自定义异常 */ BEGIN /* * 执 ...
 - Oracle数据库之PL/SQL基础
		
介绍PL/SQL之前,先介绍一个图像化工具:Oracle SQL Developer 在oracle的开发过程中, 我们难免会使用第三方开发的软件来辅助我们书写SQL, pl/sql是一个不错的sql ...
 
随机推荐
- UGUI穿透3D世界判断&&UGUI全事件监听
			
public bool isPointUI(){ PointerEventData eventDataCurrnt = new PointerEventData (EventSystem.curren ...
 - ISO 7810 协议小结
			
ISO 7816规定了Smart Card的传输协议分为 T=0 异步半双工字符传输协议 T=1 异步半双工块传输协议 T=0命令介绍 命令总是由接口设备启动,他以一个5字节的报头通知卡要做什么,然后 ...
 - ISO14443协议中,卡片对RATS,PPS,IBLOCK的处理约定
			
这几天总是看到有人因为这几条规则没处理好,结果检测时通不过,其实看看最新版的ISO14443协议就明白了. 协议中明确要求几条: 1.在激活状态后,如果收到一个无错的RATS命令后,卡片返回atr,此 ...
 - [EXCEL] 在单元格中自动输入时间和日期
			
选中需输入的单元格,直接按下“Ctrl+:”组合键可输入当前日期:如果直接按下“Ctrl+Shift+:”组合键即可输入当前时间:当然也可以在单元格中先输入其他文字然后再按以上组合键,如先输入“当前时 ...
 - 【HDOJ】4628 Pieces
			
最开始的想法是搜索,发现不对,后来发现数据量很小,可以状态压缩+DP. /* 4628 */ #include <cstdio> #include <cstring> #inc ...
 - 【转】 Linux中的工作队列
			
原文网址:http://blog.chinaunix.net/uid-20583479-id-1920134.html 工作队列一般用来做滞后的工作,比如在中断里面要做很多事,但是比较耗时,这时就可以 ...
 - Java web App 部署静态文件
			
以 Tomcat 为例子,静态文件,如 html, css, js ,无需编译,所以只需要把文件复制到 Tomcat/webapps 目录下面某个子目录,便可以了. 例子: 1. 在 Tomcat/w ...
 - Android手机令牌教程
			
Android手机令牌教程 "沉下心,你不再是小孩子了.多看书,学做人"-JeffLi告诉自己 Written In The Font 花了一个天一夜,搞了这个小东西-安卓手机令牌 ...
 - uva 10555 - Dead Fraction)(数论)
			
option=com_onlinejudge&Itemid=8&category=516&page=show_problem&problem=1496" st ...
 - 安卓(android)建立项目时失败,出现Android Manifest.xml file missing几种解决方法?(总结中)
			
安卓(android)建立项目时失败.出现AndroidManifest.xml file missing几种解决方法?(总结中) Eclipse新建项目.遇到这种问题.注意例如以下: 1.文件名称最 ...