开发者

How to duplicate hierarchical data

开发者 https://www.devze.com 2023-02-24 06:05 出处:网络
I have a table containing typical hierarchical data for tasks with an arbitrary level of subtasks. ParentID is NULL for root level tasks.:

I have a table containing typical hierarchical data for tasks with an arbitrary level of subtasks. ParentID is NULL for root level tasks.:

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

At the beginning of each month, I need to duplicate the hierarchy with new TaskID's for each task that isn't complete (TaskStatusID == Complete), then close all the original tasks. To save myself grief my first inclination would be to tackle this in c# with which I have greater proficiency than SQL but I would like to first try to understand if there is a good way to tackle this开发者_如何学Go directly in the database.

Update: @Abe I'm not sure what sample data you need particularly, and there is no desired output. I need to duplicate the structure in the table but with new TaskID's. This is for SQL Server.

@thursdaysgeek assume that if a parent task is complete then all sub-tasks are also complete. And the rule is that if the sub-tasks of a root task are all complete then I can set the root task to complete. Otherwise if a parent task is not complete but the child task is then I need to only duplicate the parent and not the child. Hope that helps.


One way would be to modify your table structure and add something like a CopiedFromTaskID column that is normally NULL.

Each month you copy all the rows for each task that isn't complete and while inserting these new rows you also update the CopiedFromTaskID column to be the ID of the task from which each row was copied. This lets you tie the new row back to the row from which it was copied.

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

Next, you run SQL to alter the ParentId of these newly-inserted rows. Since you have the CopiedFromTaskID you can use that to update the ParentID to reflect the new value, as in this 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

Lastly, you update the table one more time to make all the CopiedFromTaskID values NULL so it will be ready for the next time you run it:

UPDATE
    tblTask
SET CopiedFromTaskID = NULL
WHERE   CopiedFromTaskID IS NOT NULL

You'd want to run all these steps inside a transaction in a stored procedure, but it accomplishes what you want without cursors/loops and within the database. You would need to throw in the SQL statement to "close" all the original tasks as well, obviously.

0

精彩评论

暂无评论...
验证码 换一张
取 消