2009-10-28 78 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来更新优先级。我停止了允许用户输入。

我不确定这些答案中的哪一个是正确的,所以我会将其标记为正确,并让社区通过试验和错误来弄清楚。 :)