實現數據庫表中的流水號

實現的流水號樣式(字符+日期+流水號)如下

流水號.png

一般自己在寫小demo的時候,都是使用的純數字自增(1,2,3……)這種。相比而言,流水號形式的看起來更正規,而且可以從流水號中了解數據的添加時間及順序,當然,是不是看著更有逼格。

目前我采用的方法是,利用存儲過程來實現(可能還有很多方法),因為這種一般是在插入數據的時候使用,所以把插入數據的操作也放在了存儲過程。如果目前不知道存儲過程這個概念的小白,可以看我這篇的介紹第一次接觸存儲過程

<h3>分析</h3>
該字段由三部分組成:QQ字符 + 201706(年月,即當前日期)+ 0001(流水號,自動增長)

  1. QQ字符不用管
  2. 201706,當然是先獲取到系統當前的時間,然后拿到對應的6位數值
  3. 流水號,為了確保主鍵不重復,同一時間內,這部分流水號應該是不同的,所以流水號從 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
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容