【问题标题】:Reset Auto Increment (identity) each year每年重置自动增量(身份)
【发布时间】:2013-05-17 13:21:32
【问题描述】:

我使用的是 SQL Server 2008 R2,我想创建一个触发器。

对于每次添加(仅添加),都会像这样更新一列:

ABC-CurrentYear-AutoIncrementCode

示例:

ABC-2013-00001 

ABC-2013-1

ABC 永远不会改变

可以用YEAR(GetDate())添加当前年份,但是对于最后一部分,我遇到了困难:如何获得最后一个条目的编号以使最后一个条目+ 1?

第二个问题:

在 2014 年,自动增量计数器应重置为 1,与 2015 年等相同...

【问题讨论】:

  • 我想我会用日期时间和视图来做到这一点。
  • 您有日期时间列吗? ABC 是从哪里来的?是静态的吗?
  • 另外,您是否希望升级到 SQL Server 2012:使用此版本会容易得多

标签: sql tsql sql-server-2008-r2


【解决方案1】:

你可以这样计算新值:

SELECT 'ABC-' + 
CAST(YEAR(GETDATE()) AS VARCHAR(4)) + '-' + 
RIGHT('00000' + CAST(ISNULL(MAX(CAST(REPLACE(YourColumnName, 'ABC-' + CAST(YEAR(GETDATE()) AS VARCHAR(4)) + '-', '') AS INTEGER)), 0) + 1 AS VARCHAR(5)), 5)
FROM YourTable
WHERE YourColumnName LIKE 'ABC-' + CAST(YEAR(GETDATE()) AS VARCHAR(4)) +'%'

字符串连接的最后一部分特别复杂:

  • RIGHT 用于添加前导零
  • ISNULL 用于每年重置计数器

【讨论】:

    【解决方案2】:

    使用如下所示的示例表:

    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 函数)
    • 将它们转换为 int (CAST) - 从零开始剥离它
    • 如果 @max 为 NULL - 现在它被声明为 0 (COALESCE)
    • 将插入的 ROW_NUMBER 添加到其中 - 这很重要 - 您不能只使用 +1,因为您可能会同时添加多于 1 行(就像在演示中一样)。这就是首先需要 CTE 的全部原因。
    • 转换回 nvarchar
    • REPLICATE 用于返回 5-LEN 数量的起始零(新 LEN 计算为在数字变为 10、100、1000 时添加更少的零)

    最后,只需将 CTE 加入表并使用@code + 计算值进行更新

    我不确定是否有更简单的解决方案,但这个可行 - 我认为涵盖了所有场景。

    【讨论】:

    • 这对于并发来说是不安全的。在繁忙的系统中重叠调用会产生重复的数字,以及由于表访问和触发器中的后续写入而导致的死锁问题。
    【解决方案3】:

    但是在哪里使用这些函数。例如,如果学生表为 RegNo。需要这个 Auto-Year-Increment 属性。应该在哪里编写此代码?在存储过程中或其他地方。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-21
      • 2016-03-14
      • 2013-12-04
      • 2021-08-06
      • 2017-01-02
      • 2011-01-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多