2013-05-22 131 views
3

我正在使用SQL Server 2008 R2,並且我想創建一個觸發器。每年重置自動增量(身份)

對於每個添加(僅添加),列將更新這樣的:

ABC-CurrentYear-AutoIncrementCode 

爲例:

ABC-2013-00001 

ABC-2013-1 

ABC永遠不會改變

當年可以加上YEAR(GetDate()),但是對於最後一部分,我有困難:我怎樣才能得到最後一個條目號碼,使最後的條目+ 1?

問題二:

在2014年,自動遞增計數器應該被重置爲1,同爲2015年等...

感謝您的支持。

+0

我想我會用日期時間和視圖來做到這一點。 – Paparazzi

+0

你有日期時間專欄嗎? ABC從哪裏來?它是靜態的嗎? – gbn

+0

另外,您是否期望升級到SQL Server 2012:使用此版本更容易 – gbn

回答

0

你可以計算這樣的新值:

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重置計數器每年
0

使用一個示例表,看起來有些像這樣的事情:

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,因爲您可能同時添加多於一行(如在演示中)。這是首先需要CTE的全部原因。
  • 轉換回爲nvarchar
  • REPLICATE用於返回起始零5-LEN的量(新LEN在計算添加量少零當數成爲10個,100,1000)

在最後,只需加入CTE並使用@code +計算值進行更新

我不確定,如果可能有更簡單的解決方案,但是這個解決方案可行 - 我想涵蓋所有場景。

+1

這對於併發並不安全。在忙碌的系統中重疊呼叫會產生重複號碼,以及由於表訪問和隨後寫入觸發器而導致的死鎖問題。 – gbn

0

但是在哪裏使用這些functions.For例如,如果Student表爲RegNo。需要這個Auto-Year-Increment屬性。在哪裏寫這段代碼?在存儲過程中還是在別的地方。