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