(Oracle)预定义异常
预定义异常:
为了 Oracle 开发和维护的方便,在 Oracle 异常中,为常见的异常码定义了对应的异常名称,称为预定义异常,常见的预定义异常有:
| 异常名称 | 异常码 | 描述 |
| DUP_VAL_ON_INDEX | ORA-00001 | 试图向唯一索引列插入重复值 |
| INVALID_CURSOR | ORA-01001 | 试图进行非法游标操作。 |
| INVALID_NUMBER | ORA-01722 | 试图将字符串转换为数字 |
| NO_DATA_FOUND | ORA-01403 | SELECT INTO 语句中没有返回任何记录。 |
| TOO_MANY_ROWS | ORA-01422 | SELECT INTO 语句中返回多于 1 条记录。 |
| ZERO_DIVIDE | ORA-01476 | 试图用 0 作为除数。 |
| CURSOR_ALREADY_OPEN | ORA-06511 | 试图打开一个已经打开的游标 |
PL/SQL 中用 EXCEPTION 关键字开始异常处理。具体语法是:语法格式:异常处理
| BEGIN --可执行部分 EXCEPTION -- 异常处理开始 WHEN 异常名 1 THEN --对应异常处理 WHEN 异常名 2 THEN --对应异常处理 …… WHEN OTHERS THEN --其他异常处理 END; |
语法解析:
异常发生时,进入异常处理部分,具体的异常与若干个 WHEN 子句中指明的异常名匹配,匹配成功就进入对应的异常处理部分,如果对应不成功,则进入 OTHERS 进行处理。
案例:
代码演示:异常处理
SQL> DECLARE
2 newSal emp.sal % TYPE;
3 BEGIN
4 SELECT sal INTO newSal FROM emp;
5 EXCEPTION
6 WHEN TOO_MANY_ROWS THEN
7 dbms_output.put_line('返回的记录太多了');
8 WHEN OTHERS THEN
9 dbms_output.put_line('未知异常');
10 END;
11 /
返回的记录太多了PL/SQL procedure successfully completed
自定义异常:
除了预定义异常外,用户还可以在开发中自定义异常,自定义异常可以让用户采用与PL/SQL 引擎处理错误相同的方式进行处理,用户自定义异常的两个关键点:
1. 异常定义:在 PL/SQL 块的声明部分采用 EXCEPTION 关键字声明异常,定义方法与定义变量相同。比如声明一个 myexception 异常方法是:
myexception EXCEPTION;
2. 异常引发:在程序可执行区域,使用 RAISE 关键字进行引发。比如引发 myexception方法是:
RAISE myexception;
案例:
代码演示:自定义异常
SQL> DECLARE
2 sal emp.sal%TYPE;
3 myexp EXCEPTION; ①
4 BEGIN
5 SELECT sal INTO sal FROM emp WHERE ename='JAMES';
6 IF sal<5000 THEN
7 RAISE myexp; ②
8 END IF;
9 EXCEPTION
10 WHEN NO_DATA_FOUND THEN
11 dbms_output.put_line('NO RECORDSET FIND!');
12 WHEN MYEXP THEN ③
13 dbms_output.put_line('SAL IS TO LESS!');
14 END;
15 /
SAL IS TO LESS!
PL/SQL procedure successfully completed
代码解析:
① 用 EXCEPTION 定义一个异常变量 myexp
② 在一定条件下用 RAISE 引发异常 myexp
③ 在异常处理部分,捕获异常,如果不处理异常,该异常就抛给程序执行者。
引发应用程序异常
在 Oracle 开发中,遇到的系统异常都有对应的异常码,在应用系统开发中,用户自定义的异常也可以指定一个异常码和异常信息, Oracle 系统为用户预留了自定义异常码,其范围介于-20000 到-20999 之间的负整数。引发应用程序异常的语法是:
RAISE_APPLICATION_ERROR(异常码,异常信息)
案例:
代码演示:引发应用系统异常
SQL> DECLARE
2 sal emp.sal%TYPE;
3 myexp EXCEPTION;
4 BEGIN
5 SELECT sal INTO sal FROM emp WHERE ename='JAMES';
6 IF sal<5000 THEN
7 RAISE myexp;
8 END IF;
9 EXCEPTION
10 WHEN NO_DATA_FOUND THEN
11 dbms_output.put_line('NO RECORDSET FIND!');
12 WHEN MYEXP THEN
13 RAISE_APPLICATION_ERROR(-20001,'SAL IS TO LESS!'); ①
14 END;
15 /
ORA-20001: SAL IS TO LESS! ②
ORA-06512: 在 line 14
代码解析:
① 引发应用系统异常,指明异常码和异常信息。
② 在控制台上显示异常码和异常信息。
如果要处理未命名的内部异常,必须使用 OTHERS 异常处理器。也可以利用 PRAGMA EXCEPTION_INIT 把一个异常码与异常名绑定。PRAGMA 由编译器控制, PRAGMA 在编译时处理,而不是在运行时处理。 EXCEPTION_INIT告诉编译器将异常名与 ORACLE错误码绑定起来,这样可以通过异常名引用任意的内部异常,并且可以通过异常名为异常编写适当的异常处理器。 PRAGMA EXCEPTION_INIT 的语法是:
PRAGMA EXCEPTION_INIT(异常名,异常码)
这里的异常码可以是用户自定义的异常码,也可以是 Oracle 系统的异常码。
案例:
代码演示:PRAGMA EXCEPTION_INIT 异常
<<outterseg>>
DECLARE
null_salary EXCEPTION;
PRAGMA EXCEPTION_INIT(null_salary, -20101); ①
BEGIN
<<innerStart>> ②
DECLARE
curr_comm NUMBER;
BEGIN
SELECT comm INTO curr_comm FROM emp WHERE empno = &empno;
IF curr_comm IS NULL THEN
RAISE_APPLICATION_ERROR(-20101, 'Salary is missing'); ③
ELSE
dbms_output.put_line('有津贴');
END IF;
END;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('没有发现行');
WHEN null_salary THEN
dbms_output.put_line('津贴未知'); ④
WHEN OTHERS THEN
dbms_output.put_line('未知异常');
END;
代码解析:
① 把异常名称 null_salary 与异常码-20101 关联,该语句由于是预编译语句,必须放在声明部分。也就是说-20101 的异常名称就是 null_salary。
② 嵌套 PL/SQL 语句块
③ 在内部 PL/SQL 语句块中引发应用系统异常-20101。
④ 在外部的 PL/SQL 语句块中就可以用异常名 null_salary 进行捕获。
(Oracle)预定义异常的更多相关文章
- Oracle PL/SQL 非预定义异常、自定义异常处理、RAISE_APPLICATION_ERROR
抛出异常 Oracle有三种类型的异常错误: 1. 预定义(Predefined)异常 ORACLE预定义的异常情况大约有24个.对这种异常情况的处理,无需在程序中定义,由ORACLE自动将其引发. ...
- oracle预定义角色
角色是相关权限的集合,使用角色能够简化权限的管理.简而言之就是oracle可以事先把一系列权限集中在一起(角色),打包赋予给用户,那么用户就具有了角色的一系列权限. oracle预定义角色有25种,它 ...
- 预定义异常 - PHP手册笔记
Exception是所有异常的基类,类摘要如下: <?php class Exception { protected string $message; // 异常消息内容 protected i ...
- oracle有三种类型的异常错误: 预定义 ( Predefined )错误里面的常见错误
oracle有三种类型的异常错误: 预定义 ( Predefined )错误, 非预定义 ( Predefined )错误, 用户定义(User_define) 错误 预定义 ( Predefined ...
- 2018.6.4 Oracle数据库预定义的异常列表
declare v_ename emp.ename%type; begin select ename into v_ename from emp where empno=&gno; dbms_ ...
- .NET中那些所谓的新语法之三:系统预定义委托与Lambda表达式
开篇:在上一篇中,我们了解了匿名类.匿名方法与扩展方法等所谓的新语法,这一篇我们继续征程,看看系统预定义委托(Action/Func/Predicate)和超爱的Lambda表达式.为了方便码农们,. ...
- C++ 中常见预定义宏的使用
http://blog.csdn.net/hgl868/article/details/7058906 替代字符串: #define DOWNLOAD_IMAGE_LOG /var/log/png.l ...
- openerp经典收藏 对象的预定义方法(转载)
对象的预定义方法 原文:http://shine-it.net/index.php/topic,2159.15.html 每个OpenERP的对象都有一些预定义方法,这些方法定义在基类osv.osv中 ...
- 系统预定义委托与Lambda表达式
NET中那些所谓的新语法之三:系统预定义委托与Lambda表达式 开篇:在上一篇中,我们了解了匿名类.匿名方法与扩展方法等所谓的新语法,这一篇我们继续征程,看看系统预定义委托(Action/Fun ...
随机推荐
- 你好,Spring!
交个朋友 拿人钱财替人干活儿,在不影响工作的前提下,想做到很高频率的更新很难,但是我也尽力输出,不能为了写而写,宁缺毋滥吧. 我的想法是这样的,接下来的一段时间专门写Spring框架.整体思路就是:入 ...
- 磁盘IO工作机制
磁盘IO工作机制 ref: <深入分析java web 技术内幕> by:许令波 几种访问文件的方式 文件读取和写入的 IO 操作都是调用操作系统提供的接口,因为磁盘设备是由操作系统管理的 ...
- Could not open ServletContext resource [/WEB-INF/applicationContext.xml] 解决办法
Spring官方文档中规定,如果在上下文中没有指定contextConfigLoction配置文件的位置,则会默认去WEB-INF中去寻找对应的配置文件. 理论上classpath的默认路径是WEB- ...
- 【译】对Rust中的std::io::Error的研究
原文标题:Study of std::io::Error 原文链接:https://matklad.github.io/2020/10/15/study-of-std-io-error.html 公众 ...
- JAVA_JNI字段描述符“([Ljava/lang/String;)V”(Android)
JNI字段描述符"([Ljava/lang/String;)V "([Ljava/lang/String;)V" 它是一种对函数返回值和参数的编码.这种编码叫做JNI字段 ...
- 基于MongoDB权限管理+gridfs文件上传------云盘系统
学了一会Mongo,开始毕设的编写. 毕设目前一共分为如下模块 用户管理模块 管理员管理模块 文件管理模块 分享模块 目前已经完成了权限管理部分的后端代码.上传下载已经实现Demo.先把权限弄好后在整 ...
- SLA
服务级别协议[编辑] 维基百科,自由的百科全书 跳到导航跳到搜索 本条目可参照外语维基百科相应条目来扩充. 若您熟悉来源语言和主题,请协助参考外语维基扩充条目.请勿直接提交机械翻译,也不要翻译 ...
- JavaCV FFmpeg采集麦克风PCM音频数据
前阵子用一个JavaCV的FFmpeg库实现了YUV视频数据地采集,同样的采集PCM音频数据也可以采用JavaCV的FFmpeg库. 传送门:JavaCV FFmpeg采集摄像头YUV数据 首先引入 ...
- Android开发用到的几种常用设计模式浅谈(一):组合模式
1:应用场景 Android中对组合模式的应用,可谓是泛滥成粥,随处可见,那就是View和ViewGroup类的使用.在android UI设计,几乎所有的widget和布局类都依靠这两个类.组合模式 ...
- Python+MySQL随机试卷及答案生成程序
一.背景 本文章主要是分享如何使用Python从MySQL数据库中面抽取试题,生成的试卷每一份都不一样. 二.准备工作 1.安装Python3 下载地址:https://www.python.org/ ...