辅助表(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());
}
}