實現的流水號樣式(字符+日期+流水號)如下
流水號.png
一般自己在寫小demo的時候,都是使用的純數字自增(1,2,3……)這種。相比而言,流水號形式的看起來更正規,而且可以從流水號中了解數據的添加時間及順序,當然,是不是看著更有逼格。
目前我采用的方法是,利用存儲過程來實現(可能還有很多方法),因為這種一般是在插入數據的時候使用,所以把插入數據的操作也放在了存儲過程。如果目前不知道存儲過程這個概念的小白,可以看我這篇的介紹第一次接觸存儲過程
<h3>分析</h3>
該字段由三部分組成:QQ字符 + 201706(年月,即當前日期)+ 0001(流水號,自動增長)
- QQ字符不用管
- 201706,當然是先獲取到系統當前的時間,然后拿到對應的6位數值
- 流水號,為了確保主鍵不重復,同一時間內,這部分流水號應該是不同的,所以流水號從 0000~9999 ,即同一段時間最多會有一萬個不同的流水號。(目前不考慮9999加1之后的情況)
<h3>實現</h3>
首先建立一個test表,方便講解
create table test(
pk_id varchar(12) not null,
name varchar(10) null
)
實現201706的前一步(拿到當前的年月)
CONVERT(varchar(8), GETDATE(), 112) --獲取對應格式(20170601)的當前系統時間
實現201706,同時把得到的值賦值給一個變量(為了代碼看起來清晰)
declare @dateStr varchar(6) --定義變量
----使用substring()方法截取前6位,同時賦值變量
select @dateStr = (select SUBSTRING((Select CONVERT(varchar(8), GETDATE(), 112)),1,6))
實現0001的前一步(這里假設表中已經存在一條數據,那么它的4位流水號應該是0000,完整代碼部分中會考慮第一條數據的問題。拿到最近生產的4位流水號,新的流水號是在此基礎上得到)
----拿到上一個最近生成的pk_id
select top 1 pk_id from table test order by pk_id desc
實現0001,這只是開始
declare @maxNo varchar(4) ----定義變量
----把上訴得到的最近生產的pk_id,通過substring()方法截取最后的4位流水號,然后對其加1
select @maxNo=(Select SUBSTRING( (select top 1 pk_id from test order by pk_id desc),9,4)+1);
雖然新生成了一個流水號,但是不能直接使用,因為如果@maxNo的值不是4位數,那么就會擾亂pk_id的隊形,所以需要進行判斷
if (@maxNo < 10) begin
set @maxNo = '000' + @maxNo; --如果是1位數的話,需要在前面加3個0,補夠4位
end
else if (@maxNo < 100) begin
set @maxNo = '00' + @maxNo; --如果是2位數的話,需要在前面加2個0,補夠4位
end
else if (@maxNo < 1000) begin
set @maxNo = '0' + @maxNo; --如果是3位數的話,需要在前面加1個0,補夠4位
end
至此,分割的各個部分都實現了。為了便于插入操作,把所有值結合起來,用一個新的變量來存儲
declare @result nvarchar(12)--共計12位,前兩位為QQ,中間6位是年月,最后4位是流水號
----把之前得到的@dateStr和maxNo加上,QQ字符直接加上即可
select @result=(Select 'QQ' + @dateStr + @maxNo);
最后,把需要插入表中的數據作為參數傳遞到存儲過程中,在存儲過程中執行插入操作
@name -- 需要插入test表中的值
insert into test(pk_id,name) values(@result,@name)
這就是完整的過程,在執行插入數據的操作時,把除了pk_id之外的字段當做參數傳入到存儲過程中,在存儲過程中執行insert操作即可
完整的存儲過程代碼如下
USE [Test] ----Test是test表所在的數據庫名
GO
/****** Object: StoredProcedure [dbo].[AddData] Script Date: 06/01/2017 18:51:04 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[AddData]
@name varchar(10) ----參數,用于接收傳入的name值
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
declare @dateStr varchar(6), ----定義變量,用于存儲6位數的時間
@maxNo varchar(4), ----定義變量,用于存儲4位流水號
@result varchar(12) -----定義變量,用于存儲新生成的pk_id
----獲取到系統當前時間,并截取符合條件的6位,同時賦值給@dateStr
select @dateStr = (select SUBSTRING((Select CONVERT(varchar(8), GETDATE(), 112)),1,6))
----先判斷是否第一次向test表中插入數據(即當前表中是否存在數據)
if exists (select * from test) begin
----獲取數據表中最近產生的一個pk_id,并截取最后4位流水號,對4位流水號進行加1,最后賦值給@maxNo
select @maxNo=(Select SUBSTRING( (select top 1 pk_id from test order by pk_id desc),9,4)+1);
----對上訴的@maxNo做判斷,確保流水號一定是4位,不夠的在前面補0
if (@maxNo < 10) begin
set @maxNo = '000' + @maxNo; --如果是1位數的話,需要在前面加3個0,補夠4位
end
else if (@maxNo < 100) begin
set @maxNo = '00' + @maxNo; --如果是2位數的話,需要在前面加2個0,補夠4位
end
else if (@maxNo < 1000) begin
set @maxNo = '0' + @maxNo; --如果是3位數的話,需要在前面加1個0,補夠4位
end
----將上訴結果合成一個新的pk_id
select @result=(Select 'QQ' + @dateStr + @maxNo)
end
else
----如實當前插入的數據時第一條數據,那么直接把4位流水號設為0000
select @result = 'QQ' + @dateStr + '0000'
----將數據插入到test表中
insert into test(pk_id,name) values(@result,@name);
END