Oracle_PL/SQL(9) 例外处理
例外处理
1.例外分类:预定义例外,非预定义例外,自定义例外三种
传递例外:如果在例外处理部分exception没有捕捉例外,oracle会将例外传递到调用环境.
捕捉并处理例外:使用例外处理部分完成
exception
when exception1 then
statement1;
when exception2 then
statement2;
...
when others then --必须是例外处理部分的最后一条子句
statement_n;
...
2.预定义例外
2.1系统预定义例外有21个,如下:
dup_val_on_index:ora-00001错误。
当在唯一索引所对应的列上键入重复值时,触发例外
zero_divide:ora-01476错误。
如果使用数字值除0,则会隐含触发例外
invalid_number:ora-01722错误。
当sql语句不能有效的将字符转变成数字时,会隐含触发例外
no_date_found:ora-01403错误。
当执行select into 未返回行,或者引用了索引表未初始化的元素时,会隐含触发例外
too_many_rows:ora-01422错误。
当执行select into 语句时,如果返回超过一行,则会触发例外
access_into_null:ora-06530错误。
在引用对象属性之前,必须首先初始化对象,否则触发例外
value_error:ora-06502错误。
如果变量长度不足以容纳实际数据,则会隐含的出发例外
case_not_found:ora-06592错误。
在编写case语句时,如果在when子句中没有包含必须的条件分支(else),
并且没有包含else子句,就会触发
cursor_already_open:ora-06511错误。
当重新打开已经打开的游标时,会隐含的触发例外.
已经使用open打开了显示游标,并执行for循环,就会隐含的触发该例外
invalid_cursor:ora-01001错误。
当试图在不合法的游标上执行操作时,会隐含的触发例外.
要从未打开的游标提取数据,或者关闭未打开的游标,则触发例外
rowtype_mismatch:ora-06504错误。
宿主游标变量和pl/sql游标变量的返回类型不兼容
collection_is_null:ora-06531错误。
在给集合元素(嵌套表和varray类型)赋值前,必须首先初始化集合元素,否则触发例外
subscript_beyond_count:ora-06533错误。
当使用嵌套表或varray元素时,如果元素下标超出了嵌套表或varray元素的范围,
则回隐含的触发例外
subscript_outside_limit:ora-06532错误。
当使用嵌套表或varray元素时,如果元素下标为负值,则会隐含触发例外
login_denied:ora-01017错误。
连接数据库时,提供了不正确的用户名和口令
not_logged_on:ora-01012错误。
没有连接到数据库
program_error:ora-06501错误。
存在pl/sql内部问题,可能需要重新安装数据字典和pl/sql系统包
self_is_null:ora-30625错误。
使用对象类型时,如果在null实例上调用成员方法,则会隐含触发例外
storage_error:ora-06500错误。
如果超出内存或者内存被损坏
sys_invalid_rowid:ora-01410错误。
当字符串转变为rowid时,必须使用有效的字符串,否则触发例外
timeout_on_resource:ora-00051错误。
oracle在等待资源时出现超时错误
2.2 举例
例1: case_not_found:
ora-06592.在编写CASE语句时,如果在WHEN子句中没有包含必须的条件分支(else),
并且没有包含ELSE子句,就会触发
declare
v_sal emp.sal%type;
begin
select sal into v_sal from emp where empno=&no;
case
when v_sal<1000 then
update emp set sal=sal+100 where empno=&no;
when v_sal<2000 then
update emp set sal=sal+150 where empno=&no;
when v_sal<3000 then
update emp set sal=sal+200 where empno=&no;
end case;
--exception
-- when case_not_found then
-- dbms_output.put_line('在CASE语句中缺少与'||v_sal||'相关的条件');
end;
例2: collection_is_null:
ora-06531 在给集合元素(嵌套表和VARRAY类型)赋值前,
必须首先初始化集合元素,否则触发例外
declare
type ename_table_type is table of emp.ename%type;
ename_table ename_table_type;
begin
select ename into ename_table(1) from emp where empno=&no;
dbms_output.put_line('雇员名:'||ename_table(1));
exception
when collection_is_null then
dbms_output.put_line('必须使用构造方法初始化集合元素');
when subscript_beyond_count then
dbms_output.put_line('下标超出了集合元素的范围');
end;
3.处理非预定义例外
使用非预定义例外包括三步:
在定义部分定义例外名,
然后在例外和ORACLE错误之间建立关联,
最终在例外处理部分捕捉并处理例外.
当定义oracle错误和例外之间的关联关系时,需要使用伪过程exception_init
update emp set deptno=99 where empno=7788;
ORA-02291
declare
e_integrity exception;
pragma exception_init(e_integrity,-2291);
begin
update emp set deptno=&dno where empno=&eno;
exception
when e_integrity then
dbms_output.put_line('该部门不存在');
end;
4.处理自定义例外
自定义例外与oracle错误没有任何关联。
与预定义和非预定义不同,自定义例外必须显示触发。
declare
e_no_employee exception;
begin
update emp set deptno=20 where empno=&eno;
if sql%notfound then
raise e_no_employee;
end if;
exception
when e_no_employee then
dbms_output.put_line('该雇员不存在');
end;
5.使用例外函数
函数sqlcode用于取得oracle错误号,而sqlerrm则用于取得与之相关的错误信息。
在存储过程、函数、包中可以使用raise_application_error自定义错误号和错误消息。
5.1 sqlcode和sqlerrm
declare
v_ename emp.ename%type;
-- v_code varchar2(100);
-- v_errm varchar2(100);
begin
select ename into v_ename from emp where empno=&empno;
--exception
-- when others then
-- dbms_output.put_line('错误号:'||sqlcode);
-- dbms_output.put_line('错误信息:'||sqlerrm);
-- v_code:=sqlcode;
-- v_errm:=sqlerrm;
-- insert into error_log (id,code,errm,e_date)
-- values (seq_log.nextval,v_code,v_errm,sysdate);
end;
5.2 raise_application_error
用于在PL/SQL应用程序中自定义错误消息。
raise_application_error只能在过程,函数,包,触发器中使用,不能在匿名块中使用。
语法:raise_application_error(error_number,message);
说明:
error_number:必须在-20000和-20999之间的负整数.
message:最大2048字节
举例:
create or replace procedure proc_trans_value(p_acid_out number,p_acid_in number,p_value number)
is
l_cnt number(8):=0;
l_value account.value%type;
begin
select count(1) into l_cnt from account where accountid=p_acid_out;
if l_cnt=1 then
select value into l_value from account where accountid=p_acid_out;
if l_value>=p_value then
update account set value=value-p_value where accountid=p_acid_out;
else
raise_application_error(-20003,'[转出账户金额不足]');
end if;
else
raise_application_error(-20001,'[转出账户不存在]');
end if;
select count(1) into l_cnt from account where accountid=p_acid_in;
if l_cnt=1 then
update account set value=value+p_value where accountid=p_acid_in;
else
raise_application_error(-20002,'[转入账户不存在]');
end if;
end proc_trans_value;
insert into account values (111,'a',10000);
insert into account values (112,'b',100);
exec proc_trans_value(111,112,20000)
Oracle_PL/SQL(9) 例外处理的更多相关文章
- pl/sql进阶--例外处理
在pl/sql的执行过程中发生异常时系统所作的处理称为一个例外情况(exception).通常例外情况的种类有三种: 1.预定义的oracle例外情况oracle预定义的例外情况大约有24个,对于这种 ...
- Oracle_PL/SQL(2) 过程控制
0.检索单行数据0.1使用标量变量接受数据例1: 7788declare v_ename emp.ename%type; v_sal emp.sal%type;begin select ename,s ...
- pl/sql进阶——例外处理
在pl/sql的执行过程中发生异常时系统所作的处理称为一个例外情况(exception).通常例外情况的种类有三种: ①预定义的oracle例外情况,oracle预定义的例外情况大约有24个,对于这种 ...
- Oracle_PL/SQL(10) 定时器job
定时器job1.定义 定时器指在特定的时间执行特定的操作. 可以多次执行.说明:特定的操作:指一个完成特定功能的存储过程.多次执行:指可以每分钟.每小时.每天.每周.每月.每季度.每年等周期性的运行. ...
- Oracle_PL/SQL(8) 动态sql
动态sql0.pl/sql块的限制 不能执行ddl操作(create.drop.alter): 不能执行部分dcl操作(grant.revoke). 1.语法动态sql:在执行时才能确定要执行的sql ...
- Oracle_PL/SQL(7) 集合
pl/sql集合处理单行单列数据,可以使用标量变量:处理单行多列的数据,可以使用pl/sql记录(%rowtype,record):处理单列多行数据,可以使用pl/sql集合. pl/sql集合类型是 ...
- Oracle_PL/SQL(6) 触发器(序列、视图)
序列1.创建序列create sequence seq_alog start with 1 increment by 1 maxvalue 999999999999999999999999999 mi ...
- Oracle_PL/SQL(5) 包
包1.定义:包用于逻辑组合相关的PL/SQL类型,项和子程序,由包规范和包体组成 建立包规范:包规范是包与应用程序之间的接口,用于定义包的公用组件, 包括常量,变量,游标,过程,函数等 建立包体:用于 ...
- Oracle_PL/SQL(4) 过程和函数
create table s_sc ( SNAME VARCHAR2(20) primary key, c_grade NUMBER(6), m_grade NUMBER(6), e_grade NU ...
随机推荐
- ArcGIS案例学习笔记2_1_学校选址适宜性分析
ArcGIS案例学习笔记2_1_学校选址适宜性分析 计划时间:第二天上午 目的:学校选址,适宜性分析 内容:栅格数据分析 教程:pdf page=323 数据:chapter8/ex1/教育,生活,土 ...
- mysql-5.5.20预编译安装
1.MYSQL数据库概念 1)MYSQL是一款关系型数据库系统,数据之间有互相联系,互相的关联和调用的. 2)MYSQL数据用于存储:WEB网站用户名和密码等 3)MYSQL存储数据库是通过二维表格形 ...
- Spring Data MongDB空间索引(判断一个点Point是否在一个区域Polygon内)
这里要连接MongoDB数据库,在配置文件里:spring.data.mongodb.uri = mongodb://root:root@localhost:27017/happy 两个root分别是 ...
- 上任com的发布流程
参考:https://blog.csdn.net/qq_19674905/article/details/80268815 首先把本地代码提交到远程自己的git分支,然后merge request到m ...
- Linux简介及Linux学习路线图
一.Linux 为何物 Linux 就是一个操作系统,就像你多少已经了解的 Windows(xp,7,8)和 Max OS ,至于操作系统是什么,就不用过多解释了,如果你学习过前面的入门课程,应该会有 ...
- (转载)jenkins 安装 SVN Publisher 后向 svn 提交代码报错: E170001: Authentication required for...
问题描写叙述 安装并启动 jenkins 后,加入了 SVN Publisher 插件,然后在构建任务的“构建后操作”操作中加入了“Publish to Subversion repository”相 ...
- 使用idea+gradle建立SSM项目
目录: 一.创建一个gradle项目 二 .在gradle中创建SSM项目 一 .创建一个gradle项目 第一步: 打开我们的IDEA工具,选择创建一个新项目 第二步:这里会让你选择创建一个什么 ...
- 运行VUE的前端项目
前提条件:已经安装nodejs和cnpm ,参考前一篇文章 1.在前端项目所在的目录下执行cnpm install 下载该项目需要的包,这些包和全局配置下的包可能不同的版本cnpm会根据package ...
- 使用tor网络
在www.torproject.org/projects/torbrowser.html.en上找到合适的版本下载 下载好tor浏览器之后,解压双击Tor Browser,出现这个错误 这是因为kal ...
- 解题(StringJiaMi--字符串加密)
题目描述 有一种技巧可以对数据进行加密,它使用一个单词作为它的密匙.下面是它的工作原理:首先,选择一个单词作为密匙,如TRAILBLAZERS.如果单词中包含有重复的字母,只保留第1个,其余几个丢弃. ...