第一种实现流水号的方法: 

 注:取号全部在 RUL_Sequence 表中操作,不用管流水号所在表中的最大流水号

          可以自由配置流水号规则。

 前提:需要一个表和一个存储过程。

表如下图:

mysql生成流水序号 sql自动生成流水号_Code

 

存储过程如下:

 

[sql]
1. CREATE PROCEDURE [dbo].[Proc_GetSeqence]  
2. varchar(60),             -- 规则代码  
3. Varchar(40) OUTPUT,    -- 返回的流水号  
4. varchar(800) OUTPUT  -- 异常消息等  
5.   
6. AS  
7. /* Exec Proc_GetSeqence 'OrderNo','',''  
8. *****************************************************************  
9. 作者:     XXXXXXXXX  
10. 日期:     2013/06/30   
11. 功能描述:   获取数据表的主键流水号(INV, ASN, SO...)  
12.       
13. 主要思路:   1.取得最新流水号信息  
14.             2.把所有固定的规则信息替换成具体值,其他保持不变  
15.             eg:  
16.             规则为:        ASN<YYYY><YY><MM><XXX>ASN  
17.             当前日期为:  20130630  
18.             当前流水号为:12  
19.             最终流水号为:ASN201306013ASN  
20.               
21. ******************************************************************  
22. */  
23.   
24.   
25. /*  
26. * SET NOCOUNT ON 的作用:  
27. * 不返回受影响行数  
28. * 存储过程中包含的一些语句并不返回许多实际的数据,则该设置由于大量减少了网络流量,因此可显著提高性能。  
29. * */  
30. SET NOCOUNT ON  
31.   
32. DECLARE @SeqNowNumStr VARCHAR(20)   --当前值字符类型     
33. DECLARE @SeqNowNum BIGINT           --当前值     
34. DECLARE @year CHAR(4)               --年 YYYY  
35. DECLARE @month CHAR(2)              --月 MM  
36. DECLARE @day CHAR(2)                --日 DD  
37. DECLARE @Length INT                 --流水号长度  
38. DECLARE @DataFormat VARCHAR(50)     --流水号规则  
39. DECLARE @IniValue INT               --归零值  
40. DECLARE @ResetType VARCHAR(10)      --归零方式  
41. DECLARE @LastDate   CHAR(8)         --日期最大值           
42. DECLARE @WorkFLowStr VARCHAR(20)    --前一次调用流水号时的日期值  
43. DECLARE @DataNow CHAR(8)            --当前日期  
44. DECLARE @i INT                      --转换变量,作用参照代码上下文  
45.       
46.   
47. /*  
48. * SET XACT_ABORT ON 的作用:  
49. * 存储中的某个地方出了问题,整个事务中的语句都会回滚  
50. * */  
51. SET XACT_ABORT ON  
52. BEGIN TRY  
53.   
54.     /* 初始化变量 */  
55. SET @MessageCode='999'  
56. SET @ReturnNum = '0'  
57. SET @Length=0  
58. SET @SeqNowNum =0;  
59. SET @DataNow=CONVERT(CHAR(8),GETDATE(),112) --得到 20130704 的时间格式  
60. SET @year=SUBSTRING(@DataNow,1,4)  
61. SET @month =SUBSTRING(@DataNow,5,2)  
62. SET @day =SUBSTRING(@DataNow,7,2)  
63.        
64. Set @i=1   
65.        
66.      /***********如果有并发的正在运行,最多等待0.06秒,然后继续运行 Start*******/             
67. BEGIN TRANSACTION   
68.          wait:  
69. Update dbo.RUL_Sequence Set [IsRunning]='2' where SeqCode=@SeqCode and IsRunning='1'  
70.         If @@Rowcount=0   
71. Begin  
72. '00:00:01'  
73. Set @i=@i+1  
74. goto wait  
75. End  
76.         
77. COMMIT TRANSACTION     
78. End*******/             
79.   
80. Select @Length = [Length],@SeqNowNum=NowSeqValue,@LastDate=DateMax,@DataFormat=DataFormat  
81.         ,@ResetType=ResetType,@IniValue =InitValue  
82. From RUL_Sequence where SeqCode=@SeqCode  
83. --当前值正常情况下不可能是0  
84. begin  
85. Set @MessageCode='100'  --当前值 错误代码  
86. select @MessageCode  
87. return  
88. END  
89. --@ResetType=1 不归零 2 按日归零   3 按月归零   4按年归零  
90. and @DataNow<>@LastDate  AND @IniValue>0)  
91. OR (@ResetType=3 and @year+@month<>SUBSTRING(@LastDate,1,6) AND @IniValue>0)  
92. OR (@ResetType=4 and @year<>SUBSTRING(@LastDate,1,4) AND @IniValue>0 )  
93. BEGIN  
94. SET @SeqNowNum=@IniValue  
95. END   
96. SET  @i=@Length --@i 此时表示流水号的总长度  
97.             
98.      /***********拼流水号格式 Start*******/             
99. SET @WorkFLowStr='<'  
100.      WHILE @Length>0   
101. BEGIN  
102. SET @WorkFLowStr=@WorkFLowStr+'X'  
103. SET @Length=@Length-1  
104. END    
105. SET @WorkFLowStr=@WorkFLowStr+'>'   
106. End*******/  
107.        
108. set @SeqNowNumStr=CONVERT(VARCHAR(20),@SeqNowNum)  
109. SET @Length=@i-len(@SeqNowNumStr)  --@Length 要补零的位数(eg:@SeqNowNumStr=148 当前流水号是五位,最后流水号为00148,00 就是需要补的两位)  
110.        
111.      /***********补零操作 Start*******/             
112.      WHILE @Length>0   
113. BEGIN  
114. SET @SeqNowNumStr='0'+@SeqNowNumStr  
115. SET @Length=@Length-1  
116. END  
117. End*******/             
118.        
119. SET @ReturnNum=REPLACE( @DataFormat,'<YYYY>',@year);         -- 把规则中<YYYY>替换成相应年  
120. SET @ReturnNum=REPLACE( @ReturnNum,'<MM>',@month);               -- 把规则中<MM>替换成相应月  
121. SET @ReturnNum=REPLACE( @ReturnNum,'<DD>',@day);             -- 把规则中<DD>替换成相应日  
122. SET @ReturnNum=REPLACE( @ReturnNum,@WorkFLowStr,@SeqNowNumStr);-- 把规则中的形如<XXX>的替换成相应流水号,  
123.        
124.        
125. "1"(没有运行) ) Start*******/  
126. Begin transaction  
127.        
128. UPDATE RUL_Sequence SET NowSeqValue=@SeqNowNum+1,DateMax=@DataNow,ISRUNNING='1', EditTime=Getdate()  
129. WHERE IsRunning='2' AND  SeqCode=@SeqCode  
130. --SELECT * FROM RUL_Sequence WHERE IsRunning='2' AND SeqCode=@SeqCode  
131. -- PRINT @SeqNowNum+1  
132. Commit transaction   
133. "1"(没有运行) ) End*******/  
134.    PRINT @ReturnNum  
135. RETURN  
136.   
137. END TRY  
138.   
139. --错误捕获  
140. BEGIN   CATCH     
141. ROLLBACK TRANSACTION    
142. set @MessageCode='行号='+cast(ERROR_LINE() as varchar(10))+'错误信息'+ERROR_MESSAGE()   
143. '['+ERROR_PROCEDURE()+']'  
144.    IF @@ROWcount<=0   
145. set @MessageCode='无此编号规则'+@MessageCode  
146. SELECT  @MessageCode  
147. END   CATCH

 

RUL_Sequence表中数据如图:

 

mysql生成流水序号 sql自动生成流水号_归零_02

 

执行存储过程获得流水号:

 

Exec Proc_GetSeqence 'OrderNo','',''

 

 

第二种实现流水号的方法:

注:取流水号所在表中的最大流水号 + 1 

待研究问题:Shopping_Pay_Basic表中的流水号字段PayOrderNo遇到并发时,是否会影响用户操作?

注:第一种实现只管取号,可能造成浪费,但没有并发问题。

 


[sql]
1. --得到新编号的函数  
2. ALTER FUNCTION [dbo].[GetNextPayOrderNo](@Type char(2))  
3. RETURNS char(16)  
4. AS  
5. BEGIN  
6. DECLARE @dt CHAR(8)  
7. SELECT @dt=CONVERT(CHAR(8),GETDATE(),112)  
8. RETURN(  
9. SELECT @Type + (@dt+RIGHT(1000001+ISNULL(RIGHT(MAX(PayOrderNo),6),0),6))   
10. FROM Shopping_Pay_Basic WITH(XLOCK,PAGLOCK)  
11. WHERE PayOrderNo like @Type + @dt+'%')  
12. END  
13. -- SELECT  dbo.GetNextPayOrderNo('TT')

 

执行函数获得流水号:

 

[sql]
1. SELECT  dbo.GetNextPayOrderNo('AA'