oracle生成单据号

--创建单据号存放表
CREATE TABLE BU_TAB( 
     DOC_NUM NUMBER     --生成的单据号
);
--单据号
create table cux_doc_num(
       tab   varchar2(40),    --表名
       col   varchar2(80),    --列明
       prefix varchar2(20),   --前缀
       sequence number        --序号
);
--记得创建索引
create index cux_doc_num_u1 on cux_doc_num(tab,col,prefix);
--单据号返回函数
create or replace function get_doc_num(p_tab in varchar,  --表名
                                       p_col in varchar,  --列名
                                       p_prefix in varchar --前缀
                                       --,seq_len in integer defatlt 3,
                                       --,break_num_reuse varchar2 default 'N'   --字符型入能,默认'N',指出是否对断号进行重用,默认不重用
                                       ) 
return varchar is      --返回的单据号
pragma autonomous_transaction;
--v_result varchar2(200);
n_sequence number;
c_sequence number;
l_count    number;
--l_min_max  varchar2(3);
v_sql      varchar2(4000) := 'select nvl(max(tab.row_num),1) from (select rownum row_num from dual connect by rownum <=';
begin
  --if break_num_reuse = 'Y' THEN 
  --   l_min_max : 'min';
  --else
  --   l_min_max : 'max';
  --end if;  
  select count(*),nvl(min(sequence),0)+1  --min可以换成l_min_max
         into l_count,n_sequence
         from cux_doc_num ccs
      where ccs.tab = p_tab
        and ccs.col = p_col
        and ccs.prefix = p_prefix;
        dbms_output.put_line('l_count:'||l_count||'n_sequence:'||n_sequence);
    if l_count = 0 then
       insert into cux_doc_num
         (tab,col,prefix,sequence)
       values
         (p_tab,p_col,p_prefix,1); 
     end if;
     v_sql := v_sql || n_sequence || ') tab where not exists (select 1 from ' ||
           p_tab || ' t where to_number(substr(t.'||p_col||',length('''||p_prefix
           ||''')+1,20)) = tab.row_num'||
           ' and substr(t.' || p_col ||',1,length('''||p_prefix||'''))='''||p_prefix||''')';
      dbms_output.put_line(v_sql);
   execute immediate v_sql into c_sequence;
      dbms_output.put_line('c_sequence:'||c_sequence);
   if c_sequence = n_sequence then
      update cux_doc_num ccs
             set ccs.sequence = n_sequence
        where ccs.tab = p_tab
          and ccs.col = p_col
          and ccs.prefix = p_prefix;
     end if;
     commit;
     return p_prefix || lpad(to_char(c_sequence),10,'0');    --seq_len可以替代10,实现设置长度
  end get_doc_num;
原文地址:https://www.cnblogs.com/qinzhengquan/p/6043568.html