如何复制分层数据

Dav*_*rke 4 sql t-sql

我有一个表包含具有任意级别子任务的任务的典型分层数据.对于根级别任务,ParentIDNULL:

CREATE TABLE [dbo].[tblTask](
    [TaskID] [int] IDENTITY(1,1) NOT NULL,
    [TaskDescription] [nvarchar](255) NOT NULL,
    [TaskStatusID] [int] NOT NULL,
    [ParentID] [int] NULL
)
Run Code Online (Sandbox Code Playgroud)

在每个月的开始,我需要为每个未完成的任务(TaskStatusID == Complete)复制具有新TaskID的层次结构,然后关闭所有原始任务.为了挽救自己的悲痛,我的第一个倾向是在c#中解决这个问题,我比SQL更熟练,但我想首先尝试理解是否有一种很好的方法可以直接在数据库中解决这个问题.

更新:@Abe我不确定您需要哪些样本数据,并且没有所需的输出.我需要复制表中的结构,但需要新的TaskID.这适用于SQL Server.

@thursdaysgeek假设如果父任务完成,那么所有子任务也都完成了.规则是如果根任务的子任务全部完成,那么我可以设置根任务完成.否则,如果父任务未完成但子任务是,那么我只需复制父项而不是子项.希望有所帮助.

Sha*_*awn 5

一种方法是修改表结构并添加一些通常为NULL的CopiedFromTaskID列.

每个月都会复制每个未完成的任务的所有行,并且在插入这些新行时,还会将CopiedFromTaskID列更新为从中复制每行的任务的ID.这使您可以将新行绑定到复制它的行.

INSERT INTO
    tblTask (TaskDescription, TaskStatusID, ParentID, CopiedFromTaskID)
SELECT  TaskDescription, TaskStatusID, ParentID, TaskID
FROM    tblTask
WHERE   TaskStatusID <> Complete    --Note pseudo code here
Run Code Online (Sandbox Code Playgroud)

接下来,运行SQL以更改这些新插入的行的ParentId.由于您具有CopiedFromTaskID,因此可以使用它来更新ParentID以反映新值,如此SQL中所示:

UPDATE
    tblTask
SET
    tblTask.ParentID = InlineTable.NewTaskID
FROM
    tblTask INNER JOIN
    (
        SELECT  TaskID AS NewTaskID,
                CopiedFromTaskID AS OldTaskID
        FROM    tblTask
        WHERE   CopiedFromTaskID IS NOT NULL
    ) AS InlineTable ON tblTask.TaskID = InlineTable.OldTaskID
WHERE
    tblTask.CopiedFromTaskID IS NOT NULL
Run Code Online (Sandbox Code Playgroud)

最后,再次更新表以使所有CopiedFromTaskID值为NULL,以便下次运行时准备就绪:

UPDATE
    tblTask
SET CopiedFromTaskID = NULL
WHERE   CopiedFromTaskID IS NOT NULL
Run Code Online (Sandbox Code Playgroud)

您希望在存储过程中的事务中运行所有这些步骤,但它可以在没有游标/循环的情况下在数据库中完成您想要的任务.显然,你需要抛出SQL语句来"关闭"所有原始任务.