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.
精彩评论