SQlSERVER生成唯一编号
SQlSERVER生成唯一编号
基数表-用来存储编号前缀和类型
建表如下
CREATE TABLE [dbo].[SerialNo](
[sCode] [varchar](50) NOT NULL,
[sName] [varchar](100) NULL,
[sQZ] [varchar](50) NULL,
[sValue] [varchar](80) NULL,
CONSTRAINT [PK_SerialNo] PRIMARY KEY CLUSTERED
(
[sCode] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
这个表需要手动添加你的前缀
例如:
存储过程代码:
1 Create procedure [dbo].[GetSerialNo] 2 ( 3 @sCode varchar(50) 4 ) 5 6 as 7 8 --exec GetSerialNo 9 10 begin 11 12 Declare @sValue varchar(16), 13 14 @dToday datetime, 15 16 @sQZ varchar(50) --这个代表前缀 17 18 Begin Tran 19 20 Begin Try 21 22 -- 锁定该条记录,好多人用lock去锁,起始这里只要执行一句update就可以了 23 --在同一个事物中,执行了update语句之后就会启动锁 24 Update SerialNo set sValue=sValue where sCode=@sCode 25 26 Select @sValue = sValue From SerialNo where sCode=@sCode 27 28 Select @sQZ = sQZ From SerialNo where sCode=@sCode 29 30 -- 因子表中没有记录,插入初始值--基数据必须手动去创建 31 32 If @sValue is null 33 34 Begin 35 36 Select @sValue = convert(bigint, convert(varchar(6), getdate(), 12) + '000001') 37 38 Update SerialNo set sValue=@sValue where sCode=@sCode 39 40 end 41 42 else 43 44 Begin --因子表有记录 45 46 Select @dToday = substring(@sValue,1,6) 47 48 --如果日期相等,则加1 49 50 If @dToday = convert(varchar(6), getdate(), 12) 51 52 Select @sValue = convert(varchar(16), (convert(bigint, @sValue) + 1)) 53 54 else --如果日期不相等,则先赋值日期,流水号从1开始 55 56 Select @sValue = convert(bigint, convert(varchar(6), getdate(), 12) +'000001') 57 58 59 60 Update SerialNo set sValue =@sValue where sCode=@sCode 61 62 End 63 64 Select result = @sQZ+@sValue 65 66 Commit Tran 67 68 End Try 69 70 Begin Catch 71 72 Rollback Tran 73 74 Select result = 'Error' 75 76 End Catch 77 78 end
执行:exec dbo.GetSerialNo 'CUS'
结果:CUS150413000001
此方法可用作生成流水号,使用update启动数据库锁,并发不会重复,可读性比较好,当然使用GUID就另当别论了。