例外处理
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) 例外处理的更多相关文章

  1. pl/sql进阶--例外处理

    在pl/sql的执行过程中发生异常时系统所作的处理称为一个例外情况(exception).通常例外情况的种类有三种: 1.预定义的oracle例外情况oracle预定义的例外情况大约有24个,对于这种 ...

  2. Oracle_PL/SQL(2) 过程控制

    0.检索单行数据0.1使用标量变量接受数据例1: 7788declare v_ename emp.ename%type; v_sal emp.sal%type;begin select ename,s ...

  3. pl/sql进阶——例外处理

    在pl/sql的执行过程中发生异常时系统所作的处理称为一个例外情况(exception).通常例外情况的种类有三种: ①预定义的oracle例外情况,oracle预定义的例外情况大约有24个,对于这种 ...

  4. Oracle_PL/SQL(10) 定时器job

    定时器job1.定义 定时器指在特定的时间执行特定的操作. 可以多次执行.说明:特定的操作:指一个完成特定功能的存储过程.多次执行:指可以每分钟.每小时.每天.每周.每月.每季度.每年等周期性的运行. ...

  5. Oracle_PL/SQL(8) 动态sql

    动态sql0.pl/sql块的限制 不能执行ddl操作(create.drop.alter): 不能执行部分dcl操作(grant.revoke). 1.语法动态sql:在执行时才能确定要执行的sql ...

  6. Oracle_PL/SQL(7) 集合

    pl/sql集合处理单行单列数据,可以使用标量变量:处理单行多列的数据,可以使用pl/sql记录(%rowtype,record):处理单列多行数据,可以使用pl/sql集合. pl/sql集合类型是 ...

  7. Oracle_PL/SQL(6) 触发器(序列、视图)

    序列1.创建序列create sequence seq_alog start with 1 increment by 1 maxvalue 999999999999999999999999999 mi ...

  8. Oracle_PL/SQL(5) 包

    包1.定义:包用于逻辑组合相关的PL/SQL类型,项和子程序,由包规范和包体组成 建立包规范:包规范是包与应用程序之间的接口,用于定义包的公用组件, 包括常量,变量,游标,过程,函数等 建立包体:用于 ...

  9. Oracle_PL/SQL(4) 过程和函数

    create table s_sc ( SNAME VARCHAR2(20) primary key, c_grade NUMBER(6), m_grade NUMBER(6), e_grade NU ...

随机推荐

  1. 18.异常.md

    目录 1.try...catch 2.异常了的继承机制 2.1基本概念 2.2常用异常 2.3多异常捕获 2.4获取异常信息 2.5finally回收资源 2.6Checked异常和Runtime异常 ...

  2. Hibernate 再接触 关系映射 一对一单向外键关联

    对象之间的关系 数据库之间的关系只有外键 注意说关系的时候一定要反面也要说通 CRUD 数据库之间设计 主键关联 单向的外键关联 中间表 一对一单向外键关联 Husband.java package ...

  3. svn转git

    在Git Bash 中输入 git-svn clone http://devsvnread.uuzuonline.net/GOT_PRIVATE/server/ --no-metadata -T tr ...

  4. 学习-HTML5

    @@ 学习HTML5发现对我们开发工作者来说要方便很多,它现在还在发展阶段,在未来肯定会是主流. 我们知道HTML5目的是取代HTML4.01和XHTML1.0标准,他希望能够减少互联网富应用(RIA ...

  5. 对于“2017面向对象程序设计(Java)第三周学习总结”存在问题的反馈

    对于“2017面向对象程序设计(Java)第三周学习总结”存在问题的反馈 一:教学中存在的学习问题 “1.由于同学们平时练习不足,上课总是出现跟不上老师的节奏的现象. 2.个别同学上课不认真听讲,打开 ...

  6. MySQL动态开启general_log

    mysql下用以下命令查看general_log的开启状态. show global variables like '%general%'; 调整general_log位置,linux下一般是/tmp ...

  7. MO拆分计划行程序中写入PRODUCTIONORDERS表数据出现重复导致报错(BUG)20180502

    错误提示:ORA-00001: 违反唯一约束条件 (ABPPMGR.C0248833319_6192)ORA-06512: 在 "STG.FP_MO_SPLIT", line 19 ...

  8. 数据库表字段,DEFAULT NULL与NOT NULL DEFAULT

    为什么要把字段设置成not null 呢? 1.空值是不占用空间的 2.mysql中的NULL其实是占用空间的,下面是来自于MYSQL官方的解释 “NULL columns require addit ...

  9. PERL 正则表达式简介

    来源:脚本之家 网址:http://www.jb51.net/article/17429.htm 一.简介 二.匹配操作符 三.模式中的特殊字符 1.字符+ 2.字符 []和[^] 3.字符 *和? ...

  10. racktables 后期维护

    一.网站与数据库分离 vim secret.php #$pdo_dsn = 'mysql:host=localhost;dbname=racktables'; #$db_username = 'roo ...