3

在我的数据库中,我有如下三个表:

  • Tasks (TaskID, TaskName, TaskDescription)
  • TaskDetails (TaskID, subTaskPosition, SubTaskID)
  • Subtasks (SubTaskID, Description)

我正在尝试编写 aStored Procedure以完全删除 a SubTask,然后将另一个重新排序SubTasks为 a Task

注意事项:

  • TaskDetails链接Tasks到组成部分SubTasks
  • ASubTask可能在许多不同的任务中被引用。
  • ATask应该由SubTasks...的有序列表组成,即 1,2,3,4 而不是 1,3,4,5。

SubTask删除 a及其到 a 的链接相当容易,Task如下所示:

  • DELETE FROM TaskDetails WHERE SubTaskID = @subTaskID
  • DELETE FROM SubTasks WHERE SubTaskID = @subTaskID

但是,一旦删除了初始值,我无法理解如何重新排序表SubTasks中的另一个。在英语中,我需要执行以下操作 - “对于刚刚从中删除的所有任务,从删除行所在位置之后出现的所有字段中减去 1 ”。TaskDetailsSubTaskSubTasksubTaskPosition

任何帮助或指针表示赞赏...

戈登

4

3 回答 3

2

我认为您必须为每项任务进行更新。这可以解决问题(语法适用于 SQL Server):

DECLARE @TaskID int
DECLARE @SubTaskPosition int

DECLARE curSubTaskPositionUpdate cursor fast_forward
FOR 
    SELECT TaskID, SubTaskPosition
    FROM TaskDetails 
    WHERE SubTaskID = @SubTaskID
OPEN curSubTaskPositionUpdate
FETCH NEXT FROM curSubTaskPositionUpdate INTO @TaskID, @SubTaskPosition
WHILE @@FETCH_STATUS = 0
    BEGIN   
        UPDATE TaskDetails
        SET SubTaskPosition = SubTaskPosition - 1
        WHERE TaskID = @TaskID
        AND SubTaskPosition > @SubTaskPosition

        FETCH NEXT FROM curSubTaskPositionUpdate INTO @TaskID, @SubTaskPosition
    END
CLOSE curSubTaskPositionUpdate
DEALLOCATE curSubTaskPositionUpdate

请注意,您在从 TaskDetails 删除之前执行此操作...并且您可能希望将所有内容包装在事务中。

Gordon Edit - 我必须在更新代码中包含我的删除代码才能使其工作,否则(a)删除首先发生并且“subtaskID = @subtaskID”没有返回任何内容,或者(b)我在重新执行后删除了订购和重新订购(正确!)没有效果。

DECLARE @TaskID uniqueidentifier
DECLARE @SubTaskPosition int 

DECLARE curSubTaskPositionUpdate cursor fast_forward 
FOR  
    SELECT TaskID, SubTaskPosition 
    FROM TaskDetails  
    WHERE SubTaskID = @subTaskID 
OPEN curSubTaskPositionUpdate 
FETCH NEXT FROM curSubTaskPositionUpdate INTO @TaskID, @SubTaskPosition 
WHILE @@FETCH_STATUS = 0 
   BEGIN    
-- Delete the subTask
DELETE FROM TaskDetails
WHERE TaskID = @TaskID
AND SubTaskPosition = @SubTaskPosition 

-- Update the other subTasks
        UPDATE TaskDetails
        SET SubTaskPosition = SubTaskPosition - 1
        WHERE TaskID = @TaskID
        AND SubTaskPosition > @SubTaskPosition

        FETCH NEXT FROM curSubTaskPositionUpdate INTO @TaskID, @SubTaskPosition
    END
CLOSE curSubTaskPositionUpdate
DEALLOCATE curSubTaskPositionUpdate
于 2012-07-17T00:06:30.290 回答
2

这应该这样做:

UPDATE  TaskDetails
SET     subTaskPosition = ROW_NUMBER() OVER(PARTITION BY TaskID  ORDER BY subTaskPosition) 
WHERE   TaskID IN(  SELECT  s.TaskID 
                    FROM    TaskDetails s 
                    WHERE   SubTaskID = @subTaskID)

不需要循环...请注意,这也适用于缺少多个子任务或已为同一任务删除的情况。


好的,这是 SQL Server 的更正版本:

;WITH
  cteRows As
(
    SELECT  *,
    ROW_NUMBER() OVER(PARTITION BY TaskID  ORDER BY subTaskPosition) As NewPosition
    FROM    TaskDetails
)
UPDATE  cteRows
SET     subTaskPosition = NewPosition
WHERE   TaskID IN(  SELECT  s.TaskID 
                    FROM    TaskDetails s 
                    WHERE   SubTaskID = @subTaskID)

抱歉耽搁了 ...

于 2012-07-17T00:16:17.963 回答
0

首先获取子rask的位置,删除,更新记录:

declare @pos int
select @pos = subTaskPosition from TaskDetails where SubTaskID = @subTaskID
delete ...
delete ...
update TaskDetails set subTaskPosition = subTaskPosition + 1 where SubTaskID = @subTaskID and subTaskPosition > @pos
于 2012-07-17T00:06:08.383 回答