zoukankan      html  css  js  c++  java
  • 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 

  • 相关阅读:
    kafka-python基本使用
    RabbitMq 消息队列详解
    Socket 编程
    python 进程, 线程 ,协程,锁,协程应用到爬虫的讲解
    python中with的用法
    为什么 Elasticsearch 需要堆内存来存储数据
    面向数据的架构
    跟我一起学Redis之看完这篇比常人多会三种类型实战(又搞了几个小时)
    跟我一起学.NetCore之熟悉的接口权限验证不能少(Jwt)
    跟我一起学.NetCore之WebApi接口裸奔有风险(Jwt)
  • 原文地址:https://www.cnblogs.com/pandora2050/p/12931130.html
Copyright © 2011-2022 走看看