2014-07-07 45 views
2

我正在創建CRUD過程,該過程可以複製傳統程序,該程序根據單獨表中的「下一個ID」字段生成唯一標識。我沒有重複使用單獨的表,而是編寫了一個存儲過程來讀取表中的行數。在存儲過程中創建唯一標識以與傳統數據匹配

CREATE PROCEDURE [TLA_CreateItem] 
    @SiteReference varchar(50) 
    ,@ItemID varchar(4) 
    ,@NewUniqueID varchar(68) OUTPUT 
AS 
BEGIN 
    DECLARE @Rows varchar(12) 
    SET @Rows = (CONVERT(varchar(12), (SELECT Count(UniqueID) FROM [TLA_Items]) + 1)) 

    SET @NewUniqueID = @ItemID + @SiteReference + @Rows 

    INSERT INTO [TLA_Items] ([ItemID], [UniqueID]) 
    VALUES (@ItemID, @NewUniqueID) 

    SELECT @NewUniqueID 
END 

我已經簡化上面的代碼,但什麼是不顯示的是,TLA_Items表也有一個IDENTITY列,它需要與SQL Server 2008工作

的UniqueID的字段匹配傳統程序的模式:ItemID + SiteReference + (integer representing number of previous records)

但是,當測試這個時,我發現我的邏輯有缺陷。如果刪除行,則可以創建與現有行匹配的唯一標識。這在遺留系統中不會發生,因爲很少刪除行,並且單獨的表存儲序列中的下一個數字。

除了將下一個ID值存儲在單獨的表中,是否有更好的技術來創建與舊版模式相匹配的唯一ID?

+0

SQL Server 2008 –

回答

2

你可以有你的程序商店只有前綴(@ItemID + @SiteReference)到UniqueID和使用FOR INSERT觸發器要追加IDENTITY值作爲組件緊跟着行插入之後,這樣的事情:

CREATE TRIGGER TLA_Items_Adjust 
    ON dbo.TLA_Items 
    FOR INSERT 
AS 
BEGIN 
    UPDATE t 
    SET t.UniqueID = i.UniqueID + CAST(t.IdentityColumn AS varchar(10)) 
    FROM dbo.TLA_Items AS t 
    INNER JOIN inserted AS i 
    ON t.IdentityColumn = i.IdentityColumn 
    ; 
END 

要閱讀並返回新生成的UniqueID值作爲OUTPUT參數,以及一排,你可以使用一個表變量,並在INSERT語句中OUTPUT子句,像這樣:

CREATE PROCEDURE [TLA_CreateItem] 
    @SiteReference varchar(50) 
    ,@ItemID varchar(4) 
    ,@NewUniqueID varchar(68) OUTPUT 
AS 
BEGIN 
    DECLARE @GeneratedUniqueID TABLE (UniqueID varchar(68)); 

    INSERT INTO dbo.[TLA_Items] ([ItemID], [UniqueID]) 
    OUTPUT inserted.UniqueID INTO @GeneratedUniqueID (UniqueID) 
    VALUES (@ItemID, @ItemID + @SiteReference); 

    SELECT @NewUniqueID = UniqueID FROM @GeneratedUniqueID; 

    SELECT @NewUniqueID; 
END 

雖然不是使用OUTPUT你很可能只是讀取匹配SCOPE_IDENTITY()結果該行的值:

CREATE PROCEDURE [TLA_CreateItem] 
    @SiteReference varchar(50) 
    ,@ItemID varchar(4) 
    ,@NewUniqueID varchar(68) OUTPUT 
AS 
BEGIN 
    INSERT INTO dbo.[TLA_Items] ([ItemID], [UniqueID]) 
    VALUES (@ItemID, @ItemID + @SiteReference); 

    SELECT @NewUniqueID = UniqueID 
    FROM dbo.TLA_Items 
    WHERE IdentityColumn = SCOPE_IDENTITY(); 

    SELECT @NewUniqueID; 
END 
+0

而不是一個TRIGGER你認爲這將作爲一個簡單的更新後INSERT? –

+1

我相信會的。我想到了一個觸發器,因爲它隱式地使更新成爲同一事務的一部分。如果我選擇在過程中執行UPDATE,那麼我可能會在明確的原子事務中執行這兩個操作。 –

+0

我錯過了由SP返回生成的UniqueID的事實。更新我的答案來解決這個問題。 –

0

這聽起來像你在SQL 2008,但如果你在2012年,你可以使用一個序列來存儲遞增值。

怎麼樣永不刪除?您可以添加一個標誌到表中進行邏輯刪除。

2

這裏是另一種選擇,但請記住,會影響現有UniqueID

如果你能負擔得起表模式略有變化,你可以添加一個名爲東西柱像UniqueIDPrefix

ALTER TABLE dbo.TLA_Items 
ADD UniqueIDPrefix varchar(56) NOT NULL; 

,並重新定義UniqueID列是一個計算列:

ALTER TABLE dbo.TLA_Items 
DROP COLUMN UniqueID; 

GO 

ALTER TABLE dbo.TLA_Items 
ADD UniqueID AS UniqueIDPrefix + CAST(IdentiyColumn AS varchar(12)); 

在您的存儲過程中,您需要填寫UniqueIDPrefix而不是UniqueID(只有@ItemID + @SiteReference的結果)

INSERT INTO dbo.[TLA_Items] ([ItemID], [UniqueIDPrefix]) 
VALUES (@ItemID, @ItemID + @SiteReference); 

並使用OUTPUT或SCOPE_IDENTITY()讀取值UniqueID,如my other answer中所示。

+0

這是解決一些其他問題的優雅解決方案。謝謝 –

相關問題