編輯#1:我根據最新OP的評論
更新我的解決方案
/*
CREATE TABLE dbo.CustomSequence (
Name VARCHAR(50) NOT NULL,
Prefix VARCHAR(10) NOT NULL,
LastValue VARCHAR(50) NULL, -- All generated values will have following pattern: PrefixYYYY-SeqvNumber
LastYear SMALLINT NOT NULL,
CONSTRAINT PK_CustomSequence_Name_LastYear PRIMARY KEY (Name, LastYear),
LastNumber SMALLINT NULL
);
GO
-- Config OrderSequence 2014
INSERT dbo.CustomSequence (Name, Prefix, LastValue, LastYear, LastNumber)
VALUES ('BookSequence', 'BID', NULL, 2014, 1)
GO
-- Config OrderSequence 2017
INSERT dbo.CustomSequence (Name, Prefix, LastValue, LastYear, LastNumber)
VALUES ('BookSequence', 'BID', NULL, 2017, 1)
GO
*/
-- Generating new seq
-- IN Parameters
DECLARE @CustomSequenceName VARCHAR(50) = 'BookSequence'
DECLARE @Year SMALLINT = 2017 --YEAR(GETDATE())
DECLARE @LenOfNumber TINYINT = 4
-- End of IN Parameters
-- OUT Parameters
DECLARE @GeneratedValue VARCHAR(50)
-- End of OUT Parameters
UPDATE s
SET LastNumber = IIF(LastValue IS NULL, LastNumber, LastNumber + 1) + IIF(LastNumber = REPLICATE('9', @LenOfNumber), 1/0, 0),
@GeneratedValue = LastValue = Prefix + LTRIM(@Year) + '-' + RIGHT(REPLICATE('0', @LenOfNumber) + LTRIM(IIF(LastValue IS NULL, LastNumber, LastNumber + 1)), @LenOfNumber)
FROM dbo.CustomSequence s
WHERE s.Name = @CustomSequenceName
AND s.LastYear = @Year
-- End of Generating new seq
SELECT @GeneratedValue
SELECT * FROM dbo.CustomSequence
--> BID2017-0001, BID2017-0002, BID2017-0003, ...
注1:這與悲觀併發控制(SQL Server數據庫引擎的默認行爲)
解決工作
注2:如果我們在下面的代碼段達到10000
... IIF(LastNumber = 9999, 1/0, 0) ...
將引發異常
Msg 8134, Level 16, State 1, Line 30
Divide by zero error encountered.
The statement has been terminated.
注3:UPDATE語句可以被封裝到與@CustomSequenceName VARCHAR(50)
作爲輸入參數和@GeneratedValue VARCHAR(50) OUTPUT
作爲OUT [PUT]參數的存儲過程。
注#4:@LenOfNumber允許定製序列號的長度(默認值爲4)
編輯#2:
UPDATE語句可以用下面的INSERT + UPDATE語句的組合取代:
SET XACT_ABORT ON
BEGIN TRAN
IF NOT EXISTS(SELECT * FROM dbo.CustomSequence s WITH(HOLDLOCK) WHERE s.Name = @CustomSequenceName AND s.LastYear = @Year)
BEGIN
INSERT dbo.CustomSequence (Name, Prefix, LastValue, LastYear, LastNumber)
VALUES (@CustomSequenceName, @Prefix, NULL, @Year, 1)
END
UPDATE s
SET LastNumber = IIF(LastValue IS NULL, LastNumber, LastNumber + 1) + IIF(LastNumber = REPLICATE('9', @LenOfNumber), 1/0, 0),
@GeneratedValue = LastValue = Prefix + LTRIM(@Year) + '-' + RIGHT(REPLICATE('0', @LenOfNumber) + LTRIM(IIF(LastValue IS NULL, LastNumber, LastNumber + 1)), @LenOfNumber)
FROM dbo.CustomSequence s WITH(HOLDLOCK)
WHERE s.Name = @CustomSequenceName
AND s.LastYear = @Year
COMMIT
您可能需要在插入行時使用觸發器來執行此操作。 –
創建表格時不可以這樣做嗎? –
您的主鍵中不能有重複的值,這實際上就是您要求的。當你在某一年超過9,999個值時,你會怎麼做? –