概述
最近做一个数据检查的程序,程序的实现是不停读取配置表中的表,检查数据是否已存在,但最近程序经常会报ora-08103(网上资料说与oracle版本相关),导致整个程序无法执行,我需要的只是报错的不执行,直接跳到下一语句。
可以利用pragma exception_init对错误代码进行命名,在报错的语句块中,嵌套一个begin..end语句块。
pragma exception_init说明
如果要处理未命名的内部异常,必须使用OTHERS异常处理器或PRAGMA EXCEPTION_INIT 。PRAGMA由编译器控制,或者是对于编译器的注释。PRAGMA在编译时处理,而不是在运行时处理。EXCEPTION_INIT告诉编译器将异常名 与ORACLE错误码结合起来,这样可以通过名字引用任意的内部异常,并且可以通过名字为异常编写一适当的异常处理器。
在子程序中使用EXCEPTION_INIT的语法如下:
PRAGMA EXCEPTION_INIT(exception_name, -Oracle_error_number);
在该语法中,异常名是声明的异常,下例是其用法:
DECLARE
deadlock_detected EXCEPTION;
PRAGMA EXCEPTION_INIT(deadlock_detected, -60);
BEGIN
... -- Some operation that causes an ORA-00060 error
EXCEPTION
WHEN deadlock_detected THEN
-- handle the error
END;
以下是一个以错误代码为:-12899的例子:
create or replace procedure pr_sc_001_test_a (is_date in varchar2, oi_return out number)
/** head
* @name acrmmk#pr_sc_001_test_a
* @caption 测试A
* @type 日应用
* @parameter is_date in varchar2 统计日期,格式:YYYYMMDD
* @parameter oi_return out number 执行状态码,整数,0 正常,-1 出错
* @description 测试A
* @target acrmmk#tr_sc_001_test
* @source
* @middle
* @version 1.0
* @author 张乔
* @create-date 2011-06-12
* @TODO 无
* @version
* @mender
* @modify_date
* @modify_desc
* @copyright
*/
-- ********************************************************************************
-- 程序名称: acrmmk.pr_sc_001_test_a
-- 功能描述: 测试A
-- 输入参数: is_date - 统计日期
-- 输出参数: oi_return - 执行状态码,整数,0 正常,-1 出错
-- 输入资源:
-- 输出资源: acrmmk.tr_sc_001_test
-- 中间资源:
-- 创建人员: 张乔
-- 创建日期: 2011-06-12
-- 版本说明: V1.0
-- 修改人员:
-- 修改日期:
-- 修改原因:
-- 版本说明:
-- 公司名称:
-- ********************************************************************************
is
--vs_user_name varchar2(30); -- 用户名
vs_task_name varchar2(30); -- 任务名称
vs_table_name varchar2(30); -- 表名称
--vs_partition_name varchar2(30); -- 分区名
vs_message varchar2(200); -- 日志信息
vi_task_id integer; -- 日志ID
vd_date date; -- 统计日期
vi_cnt number(18,2);
e_12899 exception; -- 定义错误
pragma exception_init(e_12899,-12899); -- 对错误信息命名
begin
--vs_user_name := 'acrmmk';
vs_task_name := 'pr_sc_001_test_a';
vs_table_name := 'tr_sc_001_test_a';
--vs_partition_name := 'ring_fun_m';
-- 程序开始日志
acrmmk.ps_log(vs_task_name, vs_table_name, is_date, 1, null, vi_task_id);
-- 出错: 没有输入统计日期参数
if (is_date is null) then
vs_message := '没有输入统计日期参数';
acrmmk.ps_log(null, null, null, 3, vs_message, vi_task_id);
oi_return := -1;
return;
end if;
-------------------------------------------------------------
-- 得到日期类型的统计日期
vd_date := to_date(is_date, 'yyyymmdd');
--------------------------------------------------------------
-- 清除中间表数据
execute immediate 'truncate table acrmmk.tr_sc_001_test_a';
--------------------------------------------------------------
-- 需要跳转的错误语句块
begin
insert into acrmmk.tr_sc_001_test_a
(
statis_date,
type, -- varchar2(1)
deal_date
)
select
vd_date,
'Aaaaaaaaaaaaaa',
sysdate
from dual
;
commit;
exception
when e_12899 then
null;
end;
--
for i in 0..10000 loop
insert into acrmmk.tr_sc_001_test_a
(
statis_date,
type,
deal_date
)
select
vd_date,
'A',
sysdate
from dual
;
commit;
end loop;
dbms_output.put_line(oi_return);
--------------------------------------------------------------
-- 程序结束日志
acrmmk.ps_log(null, null, null, 2, null, vi_task_id);
-- 成功返回
oi_return := 0;
return;
exception
when others then
-- 得到出错信息
vs_message := substr(sqlerrm, 1, 200);
dbms_output.put_line(sqlcode);
-- 回滚事务
rollback;
-- 程序出错日志
acrmmk.ps_log(null, null, null, 3, vs_message, vi_task_id);
-- 出错返回
oi_return := -1;
return;
end;
最后
以上就是甜甜哑铃为你收集整理的pragma exception_init使用的全部内容,希望文章能够帮你解决pragma exception_init使用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复