Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL存储过程:删除后对行重新排序_Sql_Sql Server_Stored Procedures_Azure Sql Database_Sql Server 2012 - Fatal编程技术网

SQL存储过程:删除后对行重新排序

SQL存储过程:删除后对行重新排序,sql,sql-server,stored-procedures,azure-sql-database,sql-server-2012,Sql,Sql Server,Stored Procedures,Azure Sql Database,Sql Server 2012,在我的数据库中,我有三个表,如下所示: 任务(任务ID、任务名称、任务描述) TaskDetails(TaskID、子taskPosition、子TaskID) 子任务(子任务,描述) 我正在尝试编写一个存储过程以完全删除子任务,然后为任务重新排序其他子任务 注意事项: 任务详细信息将任务链接到组成部分的子任务 子任务可以在许多不同的任务中引用 一个任务应该由一个有序的子任务列表组成。。。i、 e.1,2,3,4而不是1,3,4,5 删除子任务及其到任务的链接相当容易,如下所示: 从T

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

  • 任务(任务ID、任务名称、任务描述)
  • TaskDetails(TaskID、子taskPosition、子TaskID)
  • 子任务(子任务,描述)
我正在尝试编写一个
存储过程
以完全删除
子任务
,然后为
任务
重新排序其他
子任务

注意事项:

  • 任务详细信息
    任务
    链接到组成部分的
    子任务
  • 子任务可以在许多不同的任务中引用
  • 一个
    任务
    应该由一个有序的
    子任务列表
    组成。。。i、 e.1,2,3,4而不是1,3,4,5
删除
子任务及其到
任务的链接相当容易,如下所示:

  • 从TaskDetails中删除,其中SubTaskID=@SubTaskID
  • 从子任务中删除,其中SubTaskID=@SubTaskID
但是,一旦删除了初始的
子任务
,我无法理解如何重新排序
任务详细信息
表中的其他
子任务。在英语中,我需要执行以下操作-“对于刚刚从中删除了
子任务的所有任务,从所有
子任务位置
字段中减去1,该字段位于删除行之前所在的位置之后”

感谢您的帮助或指点


Gordon

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

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

我想你必须为每项任务做一次更新。这样就可以了(语法适用于SQL Server):

请注意,在从TaskDetails中删除之前,请先执行此操作。。。您可能希望将所有内容都打包到事务中

Gordon Edit-我必须在更新代码中包含我的删除代码,否则(a)删除首先发生,并且“where 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
这应该做到:

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的更正版本:

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
;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)

抱歉耽搁了…

这是什么SQL类型的?Oracle,MS SQL Server?DB2?MySql?对不起,我应该说-MS SQL Server(2012)-尽管它也需要在Azure SQL上运行!感谢下面的回复-我稍后会尝试一下,让你知道我的进展如何。非常感谢!我喜欢!应该注意的是,它可能会更新不需要更新的行。另外,我认为应该是“WHERE TaskID IN”(“.这是一个值子查询,它与IN或EXISTS子查询同样有效(而且它们通常(但不总是)可互换)。嗨,Barry,非常感谢您的帮助。这可能是因为我没有指定我使用的是SQL Server,但我在读取时出错了“窗口函数只能出现在SELECT或ORDER BY子句中。”。有什么想法吗?非常感谢Barry-虽然这项看似简单的工作实际上相当繁重。不幸的是,您的代码在我的应用程序中不起作用。我认为原因是因为我必须在重新排序代码之前从TaskDetails表中删除子任务,所以您的”其中SubTaskID=@SubTaskID“找不到任何东西。如果你想看的话,我已经设法让下面的James代码版本正常工作了-尽管我相信你几乎有了一个更优雅的解决方案。再次感谢。感谢James,通过一些小的调整,我成功地使这个工作正常-尽管如果我可以调整的话,Barry的代码可能会更有效!