Oracle 自定义Exception Demo

根据Oracle msg_info表中用户规定的异常信息,通过procedure msginfo构建一个异常包。(表中的信息与异常包中的每一个自定义的异常一一对应)

一、定义一个异常表,自定义异常参数范围【-20999,-20000】:

--建表,存放用户自定义那个异常
create table msg_info (
     msgcode number(5)
    ,msgtype varchar2(100)
    ,msgname varchar2(100)
    ,msgtext varchar2(1000)
    ,description varchar2(1000)
)

--将自定义异常插入表中
insert into msg_info values (-20100,'EXCEPTION','Bal_too_low','Balance too low','description');
insert into msg_info values (-20200,'EXCEPTION','Emp_too_young','Employee too young','description');
...  

二、定义一个包或过程,用来生成定义包文件(异常包):

  知识点:

    1.定义和授权 directory变量;

    2.定义数组,存放字符串;

    3.文件写入;

    4.%rowcount,记录游标的行值;

--定义、授权 directory 变量
create or replace directory L_DIR as 'D:/temp';

grant read,write on directory L_DIR to SJ;
revoke read,write on directory L_DIR from SJ;

drop directory L_DIR;

过程主体如下:

create or replace procedure genpkg (
     name_in in varchar2
    ,func_def in boolean := true
    ,to_file_in in boolean := true
    ,dir_in in varchar2 := 'L_DIR'
    ,ext_in in varchar2 := 'pkg'
)
is
    cursor exc_20000
    is
        select * from msg_info 
            where msgcode between -20999 and -20000 and msgtype = 'EXCEPTION';

    -- send to screen or file?
    v_to_screen boolean := nvl(not to_file_in,true);
    fname varchar2(1000) := name_in || '.' || ext_in;
        
    --Array of output for package to store strs
    type lines_t is table of varchar2(32767) index by pls_integer;
    output lines_t;

    procedure pl(str_in in varchar2)
    is
    begin
        -- different from C style
        output(nvl(output.last,0) + 1) := str_in;
    end;

    procedure dump_output
    is
    begin
        if v_to_screen
        then
            for indx in output.first .. output.last
            loop
                dbms_output.put_line(output(indx));
            end loop;
        else
        --该处涉及文件write,必须使用exception,所以用了匿名过程 <<w_file>> declare fid utl_file.file_type; begin fid := utl_file.fopen(dir_in,fname,'w'); for indx in output.first .. output.last loop utl_file.put_line(fid,output(indx)); end loop; utl_file.fclose(fid); exception when others then dbms_output.put_line('Failure to write the file: ' || dir_in || '/' || fname); utl_file.fclose(fid); end w_file; end if; end dump_output; begin pl('create or replace package ' || name_in); pl('is'); for msg_rec in exc_20000 loop if exc_20000%rowcount > 1 then pl(' '); end if; pl(' exc_' || msg_rec.msgname || ' exception;'); pl(' en_' || msg_rec.msgname || ' constant pls_integer := ' || msg_rec.msgcode || ';'); pl(' pragma exception_init(' || 'exc_' || msg_rec.msgname || ',' || msg_rec.msgcode || ');'); if func_def then pl(' function ' || msg_rec.msgname); pl(' return pls_integer;'); end if; end loop; pl('end ' || name_in || ';'); pl('/'); if func_def then pl('create or replace package body ' || name_in); pl('is'); for msg_rec in exc_20000 loop if exc_20000%rowcount > 1 then pl(' '); end if; pl(' function ' || msg_rec.msgname); pl(' return pls_integer'); pl(' is'); pl(' begin'); pl(' return ' || 'en_' || msg_rec.msgname || ';'); pl(' end ' || msg_rec.msgname || ';'); end loop; pl('end ' || name_in || ';'); pl('/'); end if; dump_output; end genpkg;

执行genpkg('err_list'),生成err_list异常包文件如下:

create or replace package err_list
is
    exc_bal_too_low exception;
    en_bal_too_low constant pls_integer := -20100;
    pragma exception_init(exc_bal_too_low,-20100);
    function bal_too_low
        return pls_integer;
    
    exc_emp_too_young exception;
    en_emp_too_young constant pls_integer := -20200;
    pragma exception_init(exc_emp_too_young,-20200);
    function emp_too_young
        return pls_integer;
    
    exc_work_too_long exception;
    en_work_too_long constant pls_integer := -20300;
    pragma exception_init(exc_work_too_long,-20300);
    function work_too_long
        return pls_integer;
end err_list;
/
create or replace package body err_list
is
    function bal_too_low
        return pls_integer
    is
    begin
        return en_bal_too_low;
    end bal_too_low;
    
    function emp_too_young
        return pls_integer
    is
    begin
        return en_emp_too_young;
    end emp_too_young;
    
    function work_too_long
        return pls_integer
    is
    begin
        return en_work_too_long;
    end work_too_long;
end err_list;
/

 

该实例出自《OraclePLSPLUS 程序设计》 第六章 msginfo.sql 

 

posted @ 2020-05-21 15:37  pandora2050  阅读(190)  评论(0编辑  收藏  举报