我已经构建了一个触发器,我试图按顺序保持优先级,并且不允许重复的优先级值。有一些事情需要考虑。
当输入的值等于另一个值时,新优先级的项应优先于优先级,另一个应增加。
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
语句变得更高效,我真的可以用手来搞清楚它!
答案 0 :(得分:1)
如果@@ ROWCOUNT&gt;确保您回滚并引发错误(严重级16) 1.您当前编写的触发器会导致用户尝试一次插入,更新或删除多行时出现大量数据损坏。
那就是说,IronGoofy是对的:无论情况如何,你只会碰一下桌子。因此,将其分解为多个语句使代码更易于阅读/更易于维护。
如果要允许一次更新多行,则需要更改此行。逻辑可能令人生畏!
答案 1 :(得分:1)
您需要重写触发器。它假设一次只能插入/更新或删除一条记录。您无法使用该假设编写触发器,触发器对批量数据进行操作而非逐行操作。您需要加入以在更新中插入和删除。所以是的,我会尝试用case语句编写更新。
为什么这是一个删除的触发器?如果它被删除,那么就更新了。
答案 2 :(得分: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
答案 3 :(得分:0)
不应存在任何(明显的)性能差异,在任何情况下,您将向数据库发出单个更新语句。
答案 4 :(得分:0)
我决定抛弃这个想法,然后我将其留给UI来更新优先级。我已停止允许用户输入。
我不确定这些答案中的哪一个是正确的,所以我要将此标记为正确,让社区通过反复试验来解决。 :)