异常处理
希望程序继续执行
错误处理
错误处理部分位于异常的可执行部分之后,是由when语句引导多个分支构成语法如下
exception
when 错误1 [or 错误2] then
语句序列1;
when 错误3[or 错误4] then
语句序列2;
when others then
语句序列n;
错误是在标准包中由系统预定义的标准错误,或是由用户在程序说明部分自定义的错误。
凡是出现在when后面的错误都说可以捕捉的错误,其他未被捕捉的错误,将在when others部分进行统一处理,others必须是exception部分最后一个错误处理分支。如果要在该分支进一步进行判断错误种类,可以通过使用预定义函数sqlcode()和sqlerrm()来活动系统错误号和错误信息。
如果在程序子块中发生错误,但是子块没有错误处理部分,则错误将会传递到主程序中。
预定义错误
oracle系统错误很多,只有一部分常见错误在标准包中予以定义。定义错误在exception部分通过标准错误名来进行判定,并进行异常处理。常见预定义异常如下。
错误名称 | 错误代码 | 错误 |
---|---|---|
CURSOR_ALREADY_OPEN | ORA_06511 | 试图打开已经打开的游标 |
INVALID_CLUSOR | ORA_01001 | 视图使用没有打开的游标 |
DUP_VAL_ON_INDEX | ORA_00001 | 保存重复值到唯一索引约束的列中 |
ZERO_DIVIDE | ORA_01476 | 发生除数为0的除法错误。 |
INVALID_NUMBER | ORA_01722 | 视图对无效字符进数值转换 |
ROWTYPE_MISMATCH | 0RA-06504 | 主变量和游标的类型不兼容 |
VALUE_ERROR | ORA_06502 | 转换,截断或算术运算错误。 |
too_many_rows | ORA_01422 | SELECT ..INTO 语句返回多余一行的数据 |
no_data_found | ORA_01403 | SELECT ..INTO 语句没有数据返回 |
timeout_on_resource | ora_00051 | 等待资源时发生超时错误。 |
transaction_backed_out | ora_00060 | 由于死锁提交失败 |
storage_error | ora_06500 | 发生内存错误 |
program_error | ora_06501 | 发生pl/sql内部错误 |
not_logged_on | ora_01012 | 视图操作未连接的数据库 |
login_dented | ora_01017 | 在连接时提供了无效用户名或口令 |
定义错误
如果一个系统错误没有在标准包中定义,则需要在说明部分定义,定义后使用pragma exception_init来将一个定义错误同一个特别的oracle错误代码相关联,就i可以同系统预定义的错误一样,使用
语法如下
错误名 EXCEPTION ;
PRAGMA EXCEPTION_INIT(错误名,错误代码);
--注意(9i中)PRAGMAEXCEPTION_INIT(错误名,错误代码);
--eg1
declare
str varchar2(2000);
to_manyvaluesss exception;
pragma exception_init(to_manyvaluesss,-00913);
begin
str:='insert into xujb_temp4 values(''23331'',''hj'')';
execute immediate str;
excepiton
when to_manyvaluesss then
dbms_output.putline('数据值过多'||sqlcode||','||sqlerrm);
when others then
dbms_output.putline('其他未知错误'||sqlcode||','||sqlerrm);
end;
自定义异常
程序设计者可以利用引发异常的机制来进行程序设计,自己定义异常类型,可以在声明部分定义新的异常类型,用户定义的错误不能由系统来触发,必须由程序员显示的触发
错误名 EXCEPTION; -----定义异常
RAISE 错误名; ------抛出异常,手动触发
RAISE 也可以用来引发模拟系统错误,比如,RAISE ZERO_DIVIDE将引发模拟除零错误。
使用RAISE_APPLICATION_ERROR函数也可以引发异常。该函数要传递两个参数,第一个是用户自定义错误编号,的哥是参数用户自定义的错误信息。使用该函数引发的异常的编号应该在20 000和20 999之间选择
自定义异常的处理方式同前
---eg1:标签:exception,错误,处理,when,output,异常,ORA From: https://www.cnblogs.com/xjianbing/p/17549677.html
declare
my_exception1 exception;
my_exception2 exception;
sale1 number default 8000;
str varchar2(2000);
begin
insert into xujb_temp1 values('7','王小儿',sale1);
if sale1>6000 then
rasie my_exception1;
elsif sale1<1000 then
raise my_exception2;
end if;
commit;
dbms_output.put('数据录入成功');
exception
when my_exception1 then
dbms_output.put('金额超限6000录入失败');
rollback;
when my_exception2 then
dbms_output.put('金额低于下限1000录入失败');
rollback;
when others then
dbms_output.put('其他异常'||sqlcode||','||sqlerrm);
end;
--eg2使用RAISE_APPLICATION_ERROR函数抛出异常并终止程序,类似系统报错
declare
v_sale number default 10000;
begin
insert into xujb_temp1 values('7','卢路',v_sale);
if
v_sale>5000 then
raise_application_error(-20001,'超过上限金额无法录入');
elsif v_sale<1000 then
raise_application_error(-20002,'低于金额下限无法录入');
end if;
commit;
exception
when others then
dbms_output.put_line('其他异常'||sqlcode||','||sqlerrm);
end;