如何更改计算列中的一系列零
How to change the series of zeroes in a computed column
我正在使用下面的 T-SQL 创建一个带有计算列的 table,它在 'BID(The Year)-0000'
中为我提供 ID。问题是我想在年份为 changed.For 时重置 ID 中的一系列零,例如,当年份更改时 table 中的最后一个 ID 为 BID2017-0923
我想要要重置的系列,例如 'BID2018-0001'
.
这是我目前使用的T-SQL
CREATE TABLE Books
(
ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
IDCreateDate DATETIME NOT NULL DEFAULT GETDATE(),
BookID AS ('BID' + LTRIM(YEAR(IDCreateDate)) + '-' + RIGHT('0000' + LTRIM(ID), 4)),
ISBN VARCHAR(32),
BookName NVARCHAR(50),
AuthorName NVARCHAR(50),
BLanguage VARCHAR(50),
StaId int,
StuId int,
CatNo int
);
更新:
此外,我希望 ID col 根据年份记住它的最后一个 ID has.For 例如,列中的最后一个 ID 是 BID2017-0920
当我将年份更改为 2010 年时,它必须重置例如数字系列 BID2010-0001
但是当我将年份切换回 2017 年时,我不想重置系列,而是希望它从 BID2017-0921
.
开始
Edit#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 服务器数据库引擎的默认行为)
注#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
我正在使用下面的 T-SQL 创建一个带有计算列的 table,它在 'BID(The Year)-0000'
中为我提供 ID。问题是我想在年份为 changed.For 时重置 ID 中的一系列零,例如,当年份更改时 table 中的最后一个 ID 为 BID2017-0923
我想要要重置的系列,例如 'BID2018-0001'
.
这是我目前使用的T-SQL
CREATE TABLE Books
(
ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
IDCreateDate DATETIME NOT NULL DEFAULT GETDATE(),
BookID AS ('BID' + LTRIM(YEAR(IDCreateDate)) + '-' + RIGHT('0000' + LTRIM(ID), 4)),
ISBN VARCHAR(32),
BookName NVARCHAR(50),
AuthorName NVARCHAR(50),
BLanguage VARCHAR(50),
StaId int,
StuId int,
CatNo int
);
更新:
此外,我希望 ID col 根据年份记住它的最后一个 ID has.For 例如,列中的最后一个 ID 是 BID2017-0920
当我将年份更改为 2010 年时,它必须重置例如数字系列 BID2010-0001
但是当我将年份切换回 2017 年时,我不想重置系列,而是希望它从 BID2017-0921
.
Edit#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 服务器数据库引擎的默认行为)
注#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