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