一、例外分类
oracle将例外分为预定义例外、非预定义例外和自定义例外三种。
1)、预定义例外用于处理常见的oracle错误。
2)、非预定义例外用于处理预定义例外不能处理的例外。
3)、自定义例外用于处理与oracle错误无关的其它情况。 下面通过一个小案例演示如果不处理例外看会出现什么情况?
编写一个存储过程,可接收雇员的编号,并显示该雇员的姓名。
sql代码如下: 复制代码
SET SERVEROUTPUT ON;
DECLARE
V_ENAME EMP.ENAME%TYPE;
BEGIN
SELECT ENAME INTO V_ENAME FROM EMP WHERE EMPNO = &GNO;
DBMS_OUTPUT.PUT_LINE('名字:' || V_ENAME);
END;
/
复制代码
随便输入不存在的编号,回车,会抛出如下异常:
ORA-01403: 未找到数据
ORA-06512: 在line 6 例外捕获的sql代码如下: 复制代码
SET SERVEROUTPUT ON;
DECLARE
V_ENAME EMP.ENAME%TYPE;
BEGIN
SELECT ENAME INTO V_ENAME FROM EMP WHERE EMPNO = &GNO;
DBMS_OUTPUT.PUT_LINE('名字:' || V_ENAME);
EXCEPTION
WHEN no_data_found THEN
DBMS_OUTPUT.PUT_LINE('编号未找到!');
END;
/
复制代码
随便输入不存在的编号,回车,会友情提示:编号未找到! 二、处理预定义例外
预定义例外是由pl/sql所提供的系统例外。当pl/sql应用程序违反了oracle规定的限制时,则会隐含的触发一个内部例外。pl/sql为开发人员提供了二十多个预定义例外。我们给大家介绍常用的例外。
1)、case_not_found预定义例外
在开发pl/sql块中编写case语句时,如果在when子句中没有包含必须的条件分支,就会触发case_not_found例外: 复制代码
SET SERVEROUTPUT ON;
CREATE OR REPLACE PROCEDURE SP_PRO6(SPNO NUMBER) IS
V_SAL EMP.SAL%TYPE;
BEGIN
SELECT SAL INTO V_SAL FROM EMP WHERE EMPNO = SPNO;
CASE
WHEN V_SAL < 1000 THEN
UPDATE EMP SET SAL = SAL + 100 WHERE EMPNO = SPNO;
WHEN V_SAL < 2000 THEN
UPDATE EMP SET SAL = SAL + 200 WHERE EMPNO = SPNO;
END CASE;
EXCEPTION
WHEN CASE_NOT_FOUND THEN
DBMS_OUTPUT.PUT_LINE('case语句没有与' || V_SAL || '相匹配的条件');
END;
/ --调用存储过程
SQL> EXEC SP_PRO6(7369);
case语句没有与4444相匹配的条件
复制代码
2)、cursor_already_open预定义例外
当重新打开已经打开的游标时,会隐含的触发cursor_already_open例外 复制代码
DECLARE
CURSOR EMP_CURSOR IS
SELECT ENAME, SAL FROM EMP;
BEGIN
OPEN EMP_CURSOR; --声明时游标已打开,所以没必要再次打开
FOR EMP_RECORD1 IN EMP_CURSOR LOOP
DBMS_OUTPUT.PUT_LINE(EMP_RECORD1.ENAME);
END LOOP;
EXCEPTION
WHEN CURSOR_ALREADY_OPEN THEN
DBMS_OUTPUT.PUT_LINE('游标已经打开');
END;
/
复制代码
3)、dup_val_on_index预定义例外
在唯一索引所对应的列上插入重复的值时,会隐含的触发例外 复制代码
BEGIN
INSERT INTO DEPT VALUES (10, '公关部', '北京');
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
DBMS_OUTPUT.PUT_LINE('在deptno列上不能出现重复值');
END;
/
复制代码
4)、invalid_cursorn预定义例外
当试图在不合法的游标上执行操作时,会触发该例外
例如:试图从没有打开的游标提取数据,或是关闭没有打开的游标。则会触发该例外 复制代码
DECLARE
CURSOR EMP_CURSOR IS
SELECT ENAME, SAL FROM EMP;
EMP_RECORD EMP_CURSOR%ROWTYPE;
BEGIN
--open emp_cursor; --打开游标
FETCH EMP_CURSOR INTO EMP_RECORD;
DBMS_OUTPUT.PUT_LINE(EMP_RECORD.ENAME);
CLOSE EMP_CURSOR;
EXCEPTION
WHEN INVALID_CURSOR THEN
DBMS_OUTPUT.PUT_LINE('请检测游标是否打开');
END;
/
复制代码
5)、invalid_number预定义例外
当输入的数据有误时,会触发该例外
比如:数字100写成了loo就会触发该例外 复制代码
SET SERVEROUTPUT ON;
BEGIN
UPDATE EMP SET SAL = SAL + 'AAA';
EXCEPTION
WHEN INVALID_NUMBER THEN
DBMS_OUTPUT.PUT_LINE('输入的数字不正确');
END;
/
复制代码
6)、no_data_found预定义例外
下面是一个pl/sql 块,当执行select into没有返回行,就会触发该例外 复制代码
SET serveroutput ON;
DECLARE
V_SAL EMP.SAL%TYPE;
BEGIN
SELECT SAL INTO V_SAL FROM EMP WHERE ENAME = 'ljq';
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('不存在该员工');
END;
/
复制代码
7)、too_many_rows预定义例外
当执行select into语句时,如果返回超过了一行,则会触发该例外。 复制代码
DECLARE
V_ENAME EMP.ENAME%TYPE;
BEGIN
SELECT ENAME INTO V_ENAME FROM EMP;
EXCEPTION
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('返回了多行');
END;
/
复制代码
8)、zero_divide预定义例外
当执行2/0语句时,则会触发该例外
9)、value_error预定义例外
当在执行赋值操作时,如果变量的长度不足以容纳实际数据,则会触发该例外value_error 其它预定义例外(这些例外不是在pl/sql里触发的,而是在用oracle时触发的,所以取名叫其它预定义例外)
1、login_denied
当用户非法登录时,会触发该例外
2、not_logged_on
如果用户没有登录就执行dml操作,就会触发该例外
3、storage_error
如果超过了内存空间或是内存被损坏,就触发该例外
4、timeout_on_resource
如果oracle在等待资源时,出现了超时就触发该例外 三、非预定义例外
非预定义例外用于处理与预定义例外无关的oracle错误。使用预定义例外只能处理21个oracle 错误,而当使用pl/sql开发应用程序时,可能会遇到其它的一些oracle错误。比如在pl/sql块中执行dml语句时,违反了约束规定等等。在这样的情况下,也可以处理oracle的各种例外,因为非预定义例外用的不多,这里我就不举例了。 四、处理自定义例外
预定义例外和自定义例外都是与oracle错误相关的,并且出现的oracle 错误会隐含的触发相应的例外;而自定义例外与oracle 错误没有任何关联,它是由开发人员为特定情况所定义的例外.
问题:请编写一个pl/sql 块,接收一个雇员的编号,并给该雇员工资增加1000元,如果该雇员不存在,请提示。 复制代码
CREATE OR REPLACE PROCEDURE EX_TEST(SPNO NUMBER) IS
BEGIN
UPDATE EMP SET SAL = SAL + 1000 WHERE EMPNO = SPNO;
END;
/ --调用存储过程,
EXEC EX_TEST(56);
复制代码
这里,编号为56 是不存在的,刚才的报异常了,为什么现在不报异常呢?
因为刚才的是select语句
怎么解决这个问题呢? 修改代码,如下: 复制代码
--自定义例外
CREATE OR REPLACE PROCEDURE EX_TEST(SPNO NUMBER) IS
--定义一个例外
MYEX EXCEPTION;
BEGIN
--更新用户sal
UPDATE EMP SET SAL = SAL + 1000 WHERE EMPNO = SPNO;
--sql%notfound 这是表示没有update
--raise myex;触发myex
IF SQL%NOTFOUND THEN RAISE MYEX;
END IF;
EXCEPTION
WHEN MYEX THEN DBMS_OUTPUT.PUT_LINE('没有更新任何用户');
END;
/

二十七、oracle 例外的更多相关文章

  1. Bootstrap<基础二十七> 多媒体对象(Media Object)

    Bootstrap 中的多媒体对象(Media Object).这些抽象的对象样式用于创建各种类型的组件(比如:博客评论),我们可以在组件中使用图文混排,图像可以左对齐或者右对齐.媒体对象可以用更少的 ...

  2. Web 开发精华文章集锦(jQuery、HTML5、CSS3)【系列二十七】

    <Web 前端开发精华文章推荐>2014年第6期(总第27期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...

  3. Citrix 服务器虚拟化之二十七 XenApp6.5发布服务器桌面

    Citrix 服务器虚拟化之二十七  XenApp6.5发布服务器桌面 XenApp可发布以下类型的资源向用户提供信息访问,这些资源可在服务器或桌面上虚拟化: 1)  服务器桌面:发布场中服务器的整个 ...

  4. 转:二十七、Java图形化界面设计——容器(JFrame)

    转:http://blog.csdn.net/liujun13579/article/details/7756729 二十七.Java图形化界面设计——容器(JFrame) 程序是为了方便用户使用的, ...

  5. 二十七、Java图形化界面设计——容器(JFrame)

    摘自http://blog.csdn.net/liujun13579/article/details/7756729 二十七.Java图形化界面设计--容器(JFrame) 程序是为了方便用户使用的, ...

  6. WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现](提供模拟程序)

    原文:WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现](提供模拟程序) 基于HTTP-GET的元数据发布方式与基于WS-MEX原理类似,但是ServiceMetad ...

  7. WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于WS-MEX的实现](提供模拟程序)

    原文:WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于WS-MEX的实现](提供模拟程序) 通过<如何将一个服务发布成WSDL[编程篇]>的介绍我们知道了如何可以通过编程或者配 ...

  8. WCF技术剖析之二十七: 如何将一个服务发布成WSDL[编程篇]

    原文:WCF技术剖析之二十七: 如何将一个服务发布成WSDL[编程篇] 对于WCF服务端元数据架构体系来说,通过MetadataExporter将服务的终结点导出成MetadataSet(参考< ...

  9. VMware vSphere 服务器虚拟化之二十七桌面虚拟化之View中使用Thinapp软件虚拟化

    VMware vSphere 服务器虚拟化之二十七桌面虚拟化之View中使用Thinapp软件虚拟化 VMware ThinApp 应用程序虚拟化软件是无代理解决方案,通过将应用程序隔离并封装为EXE ...

  10. 第一百二十七节,JavaScript,JSON数据类型转换,数据转换成字符串,字符串转换成数据

    第一百二十七节,JavaScript,JSON数据类型转换,数据转换成字符串,字符串转换成数据 学习要点: 1.JSON语法 2.解析和序列化 前两章我们探讨了XML的结构化数据,但开发人员还是觉得这 ...

随机推荐

  1. 用友CDM系统,将货位间商品移库单(一步)修改为内调出入库单(一步)方法使用

    客户一般只购买CDM供应链系统,但是只买供应链模块不能进行内调等操作,据说插件将近15万(坑爹~~~) 货位间商品移库单和内调差不多,区别是货位间移库默认只能选择登陆账号所属机构的货位. 解决方案:分 ...

  2. 编程利用利用curses库编程开始

    时间紧张,先记一笔,后续优化与完善. curses库常用函数: 注意编译时要用这样的格式:gcc xxx.c -l curses -o xxx 第一个小例子: include <stdio.h& ...

  3. Java的Exception和Error面试题10问10答

    在Java核心知识的面试中,你总能碰到关于 处理Exception和Error的面试题.Exception处理是Java应用开发中一个非常重要的方面,也是编写强健而稳定的Java程序的关键,这自然使它 ...

  4. 图像预处理(Evision)

    Convolution //采用线性过滤Linear combination of neighboring pixels using a convolution kernel−Pre-defined ...

  5. Andy的生活

    Andy是一个善良的男孩,希望优雅地生活. 现实是残酷的. 现实是,Andy像狗一样活着. Andy犯的错是,错误地认为狗一样的生活将在高考结束的那一刻结束. 大学四年时间根本没有静下心来学习,却在生 ...

  6. shell 读取文件

    #!/bin/bash content=`cat test.txt` echo "begin" for i in $content do echo $i done 读取前10行 t ...

  7. linux kernel 编译

    lin

  8. iOS7之后经过滑动返回导航栏隐藏和显示带来的坑(转载)

    iOS7之后经过滑动返回导航栏隐藏和显示带来的坑 Apple 自从iOS7之后增加了屏幕边缘右滑返回交互的支持,再配合UINavigationController的交换动画,pop上一级的操作变的非常 ...

  9. 【Python】回文

    首先判断一个字符串是否回文: def isPlalind(s): if len(s) == 1: return True else: return s[0] == s[-1] and isPlalin ...

  10. iOSAPP添加启动页

    如果你在开发过程中出现屏幕显示内容比例不正常或者显示不全的问题,你发现不是代码或者约束的问题,那么很可能是启动页没有添加或者添加不全的原因,下面配一张问题图片上下黑屏 添加启动页步骤如下图 (1) ( ...