根据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