辅助表(RUL_SEQUENCE):
表中数据如图:
辅助存储过程(Proc_GetSeqence):
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
程序中调用:
辅助枚举:
#region 规则代码(生成流水号的) public enum FlowNoRule { /// <summary> /// 英文数据批次号 /// </summary> EnBatchNo, /// <summary> /// 中文数据批次号 /// </summary> CnBatchNo } #endregion
函数:
public string GetNextNo(Helper.EnumHelper.FlowNoRule rule) { string sql = "proc_getseqence"; OracleParameter[] param = { new OracleParameter("seqcode",OracleType.VarChar,20), new OracleParameter("returnnum",OracleType.VarChar,100), new OracleParameter("messagecode",OracleType.VarChar,500) }; param[0].Direction = ParameterDirection.Input; param[0].Value = rule.ToString(); param[1].Direction = ParameterDirection.Output; param[2].Direction = ParameterDirection.Output; OracleHelper.ExecuteNonQuery(CommandType.StoredProcedure, sql, param); if (param[2].Value.ToString() == "888") { //调用成功,返回最新流水号 return param[1].Value.ToString(); } else { //调用失败,返回错误消息 throw new Exception(param[2].Value.ToString()); } }