使用一个类似于这样的示例表:
CREATE TABLE MyTable (id INT IDENTITY(1,1), someCol NVARCHAR(20), codeCol NVARCHAR(20))
有一个id列,一些随机值列和第三列存储您的代码。
您的触发器可能看起来像这样:
CREATE TRIGGER tgInsertMyTable ON myTable
AFTER INSERT
AS
BEGIN
DECLARE @code NVARCHAR(20)
SELECT @code = 'ABC-' + CAST(YEAR(GETDATE()) AS NVARCHAR(4)) + '-'
DECLARE @max NVARCHAR(20)
SELECT @max = codeCol FROM dbo.myTable mts WHERE mts.codeCol LIKE @code + '%'
;WITH CTE_UPD AS
(
SELECT REPLICATE('0', 5-LEN(CAST(COALESCE(CAST(RIGHT(@max,5) AS INT),0) + ROW_NUMBER() OVER (ORDER BY ins.ID) AS NVARCHAR(5)))) + CAST(COALESCE(CAST(RIGHT(@max,5) AS INT),0) + ROW_NUMBER() OVER (ORDER BY ins.ID) AS NVARCHAR(5)) AS nextNo, id
FROM INSERTED ins
)
UPDATE mt
SET mt.CodeCol = @code + nextNo
FROM dbo.MyTable mt
INNER JOIN CTE_UPD ins ON ins.ID = mt.ID
END
我知道有些地方看起来很复杂,所以我会尽量解释一下,但首先 - 这里有一个演示,它可以正常工作:
SQLFiddle DEMO
所以,首先我在@code
变量中设置了所需的代码前缀 - 这是没有增量的部分。
第二步 - 我在表中现有行中搜索具有相同前缀的最大值 - 并将其存储在变量@max
中。
第三部分是CTE - 它用于查找下一个增量值。
- 从最大值中仅获取最后5个字符(使用RIGHT函数)
- 将它们转换为整数(CAST)- 从起始零开始去除
- 如果@max为NULL- 现在声明为0(COALESCE)
- 将插入的ROW_NUMBER添加到其中 - 这很重要 - 您不能仅使用+1,因为您可能同时添加多行(例如演示)。这就是首先需要CTE的整个原因。
- 再次转换为nvarchar
- REPLICATE用于返回起始零,数量为5-LEN(新LEN被计算以在数字变为10,100,1000时添加较少的零)
最后,只需将CTE连接到表并使用@code + 计算值进行更新即可
我不确定是否可能存在更简单的解决方案,但这个解决方案可以工作-并且我认为涵盖了所有情况。