我是靠谱客的博主 甜甜哑铃,最近开发中收集的这篇文章主要介绍pragma exception_init使用,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

最近做一个数据检查的程序,程序的实现是不停读取配置表中的表,检查数据是否已存在,但最近程序经常会报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使用所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部