Oracle中异常的处理

异常(EXCEPTION)情况处理是用来处理程序在运行从出现可预见或者不可预见的情况,它可以处理Oracle预定义的异常和用户自定义的错误。PLSQL块中一旦产生异常而没有做异常处理会自动终止程序。

异常的分类

  1. Oracle预定义异常,有异常名称,异常代码和错误原因,这类异常可以直接在异常处理中直接使用,。
  2. 非预定义异常,有错误代码和错误原因,但是没有异常名称,需要事先声明异常名称才可以使用。
  3. 自定义异常,用户可以自己声明异常的发生条件和名称,灵活使用。

语法

Oracle的异常处理和Java中的异常处理try catch非常的相似。

--异常处理以exception关键字开始,以end结束
begin
  可执行代码;
exception
when 异常1 or 异常2 then
	处理程序...
when 异常3 then
	处理程序..
[when others then]
	处理程序...
end;

预定义异常

常见的预定义异常
错误号   	异常错误信息名称  		说明
ORA-0001  Dup_val_on_index  		违反了唯一性限制
ORA-0051  Timeout_on_resource  		在等待资源时发生超时
ORA-0061  Transaction_backed_out  	由于发生死锁事务被撤消
ORA-1001  Invalid-CURSOR   			试图使用一个无效的游标
ORA-1012  Not_logged_on  			没有连接到ORACLE
ORA-1017  Login_denied 				无效的用户名/口令
ORA-1403  no_data_found  			SELECT INTO没有找到数据
ORA-1422  too_many_rows  			SELECT INTO 返回多行
ORA-1476  Zero_divide   			试图被零除
ORA-1722  Invalid_NUMBER   			转换一个数字失败
ORA-6500  Storage_error  			内存不够引发的内部错误
ORA-6501  Program_error  			内部错误
ORA-6502  Value_error   			转换或截断错误
ORA-6504  Rowtype_mismatch  		宿主游标变量与 PL/SQL变量有不兼容行类型
ORA-6511  CURSOR_already_OPEN  		试图打开一个已处于打开状态的游标
ORA-6530  Access_INTO_null  		试图为null 对象的属性赋值
ORA-6531  Collection_is_null 		试图将Exists 以外的集合( collection)方法应用于一个null pl/sql 表上或varray上
ORA-6532  Subscript_outside_limit   对嵌套或varray索引得引用超出声明范围以外
ORA-6533  Subscript_beyond_count  	对嵌套或varray 索引得引用大于集合中元素的个数.

示例

--no_data_found、too_many_rows,通过select into 给变量赋值时,容易报这两个错误
declare
   v_id   number;
begin
   with
   tab as(select 1 id from dual
          union all
          select 1 id from dual) --with tab as是预定义临时表
   select id
     into v_id  --如果不做处理会报no_data_found这个错误
     from tab
    where id=3;
exception 
   when no_data_found then --Oracle预定义异常,直接直接根据名称使用
      v_id := null;
      dbms_output.put_line('no_data_found');
   when too_many_rows then
      v_id := null;
      dbms_output.put_line('too_many_rows');
end;

declare
   v_id   number;
begin
   with
   tab as(select 1 id from dual
          union all
          select 1 id from dual)
   select id
     into v_id --如果不做处理会报too_many_rows错误
     from tab
    where id=3;
exception 
   when no_data_found then
      v_id := null;
      dbms_output.put_line('no_data_found');
   when too_many_rows then
      v_id := null;
      dbms_output.put_line('too_many_rows');
end;

非预定义异常

针对非预定义的异常,可以定义一个异常,并与错误代码关联,就可以象预定义异常一样处理了
语法

--声明异常
异常名称 exception;
--异常代码绑定
异常名称 exception_init(异常名称,错误代码);

示例

--创建环境
create table gsc_test(id number(10),name varchar2(10));
alter table gsc_test modify name not null;

declare
   null_value  exception;
   pragma exception_init(null_value,-01400);
begin
   insert into gsc_test (id,name) values(1,null); --如果不处理会报ORA-01400: cannot insert NULL into错误
exception 
   when null_value then
      dbms_output.put_line('插入空值');
end;
--注意,ORA-01031: insufficient privileges 这类权限校验的,没法预定义异常

自定义异常

语法

--抛出自定义异常,无需绑定异常代码
declare
   异常名称 exception
begin
   raise 异常名;--抛出异常
exception
	when 异常名 then --处理异常
end;
--抛出预定义异常,无需声明异常
declare
begin
   raise 预定义异常名;--抛出异常
exception
	when 预定义异常名 then --处理异常
end;
--抛出非预定义异常,比较特殊,使用raise_application_error抛出异常
begin
	raise_application_error(代码号,异常的明细);
	--代码号的范围在-20000至-20999之间随意填写
end

示例

--raise_application_error抛出的异常,可以用exception when others 来处理
declare
   v_result     number;
   v_sqlerrm    varchar2(4000);
begin
   
   v_result := 0;
   for i in 1..100
   loop
      v_result := v_result + i;
      if v_result >=1000 then
         raise_application_error(-20001,'超出范围啦'); --抛出非预定义异常
      end if;
   end loop;
exception when others then
   v_sqlerrm := substrb(dbms_utility.format_error_backtrace||sqlerrm, 1, 4000); 
 --dbms_utility.format_error_backtrace是获取报错的行数,sqlerrm是报错的内容,也就是我们定义的'超出范围啦'。
 --这段异常拼接语句非常常用,能够帮助我们快速了解出错的行数和报错信息。
   dbms_output.put_line(v_sqlerrm);
end;

输出

ORA-06512: 在 line 11
ORA-20001: 超出范围啦
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值