2009-10-28 55 views
1

我已經構建了一個觸發器,我試圖按順序保持優先級,並且不允許重複的優先級值。有一些事情要考慮。多個SQL UPDATE語句或單個CASE在裏面?

  1. 用戶可以自由形式的優先級。
  2. 沒有什麼從採摘相同的優先級的另一項阻止他們。
  3. 當輸入一個值等於另一個值的新優先項目應優先考慮的優先級和其他應增加。

    CREATE TRIGGER dbo.trg_Priority 
        ON dbo.Stories 
        AFTER INSERT,UPDATE,DELETE 
    AS 
    BEGIN 
        SET NOCOUNT ON; 
    
    -- Insert statements for trigger here 
    DECLARE @StoryId INT 
    DECLARE @OldLocation INT 
    DECLARE @NewLocation INT 
    
    SELECT @NewLocation = Priority, @StoryId = StoryId FROM INSERTED 
    SELECT @OldLocation = Priority FROM DELETED 
    
    IF @NewLocation = @OldLocation 
        RETURN; 
    
    IF @NewLocation IS NULL 
    BEGIN 
        UPDATE Stories SET 
         Priority = Priority - 1 
        WHERE Priority > @OldLocation 
    END 
    
    IF @NewLocation > @OldLocation 
    BEGIN 
        UPDATE Stories SET 
         Priority = Priority + 1 
        WHERE Priority >= @NewLocation 
        AND StoryId <> @StoryId 
    END 
    
    IF @NewLocation < @OldLocation 
    BEGIN 
        UPDATE Stories SET 
         Priority = Priority + 1 
        WHERE Priority >= @NewLocation 
        AND Priority < @OldLocation 
        AND StoryId <> @StoryId 
    END 
    END 
    GO 
    

所以如果有關注的領域隨意說話,我沒有測試過這觸發了一大堆。我最終想知道的是,如果我應該嘗試使用case語句將其轉換爲單個更新。 (如果甚至可能的話)

如果將它作爲單個UPDATE聲明會更高效,我真的可以用一隻手來搞清楚它!

回答

1

您需要重寫觸發器。它假設一次只能插入/更新或刪除一條記錄。你不能用這個假設來編寫觸發器,觸發器不是逐行地操作批量數據。您需要加入才能在更新中插入和刪除。所以是的,我會嘗試用case語句編寫更新。

爲什麼這是一個刪除觸發器?如果它被刪除,那就贏了;

0

如何:

UPDATE Stories SET Priority = CASE 
    WHEN Priority > @OldLocation THEN Priority-1 
    WHEN Priority >= @NewLocation AND StoryID <> @StoryID THEN Priority+1 
    WHEN Priority >= @NewLocation AND @Priority < @OldLocation And StoryID <> StoryID THEN Priority +1 
END 
GO 
0

不應該有任何(明顯)的性能差異,在任何情況下,你會發出一個更新語句到數據庫。

1

確保您回滾並在@@ ROWCOUNT> 1時引發錯誤(嚴重性爲16)。您當前寫入的觸發器會導致用戶試圖一次插入,更新或刪除多行的大量數據損壞。

也就是說,IronGoofy是正確的:你只能一次觸摸表,不管條件。因此,將其分解爲多個語句會使代碼更易於閱讀/維護。

如果你允許多個行一次更新,你需要改變這一點。邏輯可能令人望而生畏!

0

我決定拋棄這個想法,我把它留給UI來更新優先級。我停止了允許用戶輸入。

我不確定這些答案中的哪一個是正確的,所以我會將其標記爲正確,並讓社區通過試驗和錯誤來弄清楚。 :)