Oracle生成流水号

  • 流水号规则表Rul_Sequence:

 

规则表中的数据:

生成流水号辅助的存储过程:

CREATE OR REPLACE PROCEDURE Proc_GetSeqence(SeqCode in  varchar2,ReturnNum out Varchar2,MessageCode out varchar2 )    -- 异常消息等
is
seqNowNumStr VARCHAR2(20);
SeqNowNum int;            --当前值
year CHAR(4);                --年 YYYY
month CHAR(2);                --月 MM
day CHAR(2)    ;            --日 DD
NowLength int;                    --流水号长度
DataFormat VARCHAR2(50);        --流水号规则
IniValue int;                --归零值
ResetType VARCHAR2(10);        --归零方式
LastDate    CHAR(8);            --日期最大值
WorkFLowStr VARCHAR2(20);     --前一次调用流水号时的日期值
DataNow CHAR(8);            --当前日期
i int;                        --转换变量,作用参照代码上下文
begin

    /* 初始化变量 */
     MessageCode:='888';--成功执行
     ReturnNum := '0';
     NowLength:=0;
     SeqNowNum :=0;
     DataNow:=to_char(sysdate,'yyyymmdd'); --得到 20130704 的时间格式
     year:=substr(DataNow,1,4);
     month :=substr(DataNow,5,2);
     day :=substr(DataNow,7,2);
   i:=1 ;

   Select   Value_length,Now_SeqValue,Date_Max,Data_Format,Reset_Type,Init_Value
           into NowLength,SeqNowNum,LastDate,DataFormat,ResetType,IniValue
            From RUL_Sequence where Seq_Code=SeqCode;

 <<wait>>
 Update RUL_Sequence Set Is_Running='2' where Seq_Code=SeqCode and is_running='1';
 if sql%rowcount=0 then
   /***********如果有并发的正在运行,最多等待1秒,然后继续运行 *******/
   dbms_lock.sleep(1); --grant execute on dbms_lock to dhlink 需要授权
   goto wait;
end if;
commit;

If (ResetType=2 and DataNow<>LastDate  AND IniValue>0)
        OR (ResetType=3 and year||month<>substr(LastDate,1,6) AND IniValue>0)
        OR (ResetType=4 and year<>substr(LastDate,1,4) AND IniValue>0 ) then
            SeqNowNum:=IniValue;
 end if;

i:=NowLength; --i 此时表示流水号的总长度
WorkFLowStr:='<';
WHILE NowLength>0
     loop
         WorkFLowStr:=WorkFLowStr||'X';
         NowLength:=NowLength-1;
     end loop;
     WorkFLowStr:=WorkFLowStr||'>' ;
     /***********拼流水号格式 End*******/

     SeqNowNumStr:=to_char(SeqNowNum);
     NowLength:=i-length(seqNowNumStr);

     /***********补零操作 Start*******/
     WHILE NowLength>0
     loop
         SeqNowNumStr:='0'||SeqNowNumStr;
         NowLength:=NowLength-1;
     end loop;
     /***********补零操作 End*******/

     ReturnNum:=REPLACE(DataFormat,'<YYYY>',year);            -- 把规则中<YYYY>替换成相应年
     ReturnNum:=REPLACE( ReturnNum,'<MM>',month);                -- 把规则中<MM>替换成相应月
     ReturnNum:=REPLACE( ReturnNum,'<DD>',day);                -- 把规则中<DD>替换成相应日
     ReturnNum:=REPLACE( ReturnNum,WorkFLowStr,SeqNowNumStr);-- 把规则中的形如<XXX>的替换成相应流水号,


     /***********更新当前流水值为最大流水号、上一个流水号生成时间和运行标记(运行标记置为"1"(没有运行) ) Start*******/

     UPDATE RUL_Sequence SET Now_SeqValue=SeqNowNum+1,Date_Max=DataNow,IS_RUNNING='1', Edit_Time=SYSDATE
     WHERE Is_Running='2' AND  Seq_Code=SeqCode;
     commit;
     /***********更新当前流水值为最大流水号、上一个流水号生成时间和运行标记(运行标记置为"1"(没有运行) ) End*******/
exception
when others then
rollback;
MessageCode:='无此编号规则'||MessageCode;

end Proc_GetSeqence;


-- SELECT * FROM RUL_Sequence

 

posted @ 2015-05-05 13:55  安小强  阅读(2330)  评论(0)    收藏  举报