我有一個存儲發票的SQL Server表讓我們稱之爲發票。我需要實現發票的連續自動編號功能(不是不連續的自動功能)。此外,我應該注意併發問題,例如用戶A和用戶B同時開具發票,但兩張發票不應該有相同的數字(顯然)。連續自動編號
什麼是T-SQL中理想的實現方法?
我有一個存儲發票的SQL Server表讓我們稱之爲發票。我需要實現發票的連續自動編號功能(不是不連續的自動功能)。此外,我應該注意併發問題,例如用戶A和用戶B同時開具發票,但兩張發票不應該有相同的數字(顯然)。連續自動編號
什麼是T-SQL中理想的實現方法?
我們做了類似的一種方式是創建一個名爲useID
的表,其中只有一列名爲[ID]
。我們使用Integer數據類型。該表也只有一行。更多關於這一點。
現在,每次我們需要記錄事件時,我們都會從useID
開始SELECT
,然後運行我們的交易,並將此[ID]
值用於跟蹤目的。在我們有SELECT
編輯[ID]
之後,我們將useID
中的值增加1(或者我們需要的系統)。通過這種方式,我們保持獨特和連續的值。我們可以從[ID]
值的目標中刪除,而不會影響新值[ID]
的順序。這樣的表現非常好,因爲我們每晚使用這種方式進行約1000萬筆交易,並且我們每3個月左右重置一次起始價值,因爲我們沒有將這些項目保留很長時間。
一個IDENTITY列。
如果您需要一個字母數字的發票號碼,我建議您使用所需的格式更新您的問題。
如果您刪除記錄,在INSERT過程中遇到錯誤,將包含INSERT的事務回滾到表中,或者種子由相關的dbcc命令更新,則只會存在間隙。
如果你真的需要重新使用差距(而且我確實不會這樣做,比如發票,例如,在你的例子中,發票#32會有更晚的日期,然後發票#190 ......):那麼你在可序列化的事務中,可以找到最低的空閒值,設置標識插入,插入具有該Id值的行,然後設置標識插入並提交事務。
像這樣(未經):
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
SET IDENTITY_INSERT dbo.myTable ON
DECLARE @minId int = -1
;WITH cterows(Id, rownum)
AS
(
SELECT Id, row_number() OVER(ORDER BY Id ASC) AS rownum
)
SELECT @minId = MIN(rownum) FROM cterows
WHERE Id <> rownum
IF (@minId IS NOT NULL AND @minId <> -1)
BEGIN
-- found a gap
-- Insert at @minId
END
ELSE
BEGIN
-- No gap, INSERT as normal
END
SET IDENTITY_INSERT dbo.myTable OFF;
COMMIT
如果不是必要的,這些數字要繼續,你可以創建隨機數,但如果要繼續則可以使該列IDENTITY
colunm
檢查這個post來創建隨機數
,您可以撥打SQL Varchar
列字母數字發票號,在這裏,你需要不生成唯一的發票或者可以使用IDENTITY
列。
如果我不必使用標識列? – Ioannis
我的理解是,SQL Server IDENTITY列是按照它們的方式實現的,這是因爲兩個或多或少同等重要的問題:併發性和性能。由於前者,你保證有獨特的價值,但你必須忍受可能的差距,因爲後者。現在你正試圖消除差距的可能性(在你自己的IDENTITY實現中)。你認爲你會遭受什麼樣的回報? –
我並不十分清楚......例如,最後一張發票的編號爲190,我刪除了發票#32。然後,新插入的發票將需要數字32.這就是我不需要身份的原因。 – Ioannis