2011-04-13 5 views
4

임의의 하위 수준의 작업을 수행하는 데 필요한 일반적인 계층 적 데이터가 포함 된 테이블이 있습니다. ParentID 루트 수준의 작업에 대한 NULL : 매월 초에계층 적 데이터를 복제하는 방법

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

, 나는 새로운 TaskID를의 완료되지 않은 각 작업과 계층 구조 (를 복제 할 필요가 TaskStatusID == 완료) 모든 원래 작업을 닫습니다. 내 슬픔을 덜기 위해 첫 번째 성향은 C#에서 SQL보다 뛰어난 능력을 발휘하는 것이지만 데이터베이스에서 직접 처리 할 수있는 좋은 방법이 있는지 먼저 알고 싶습니다.

업데이트 : @Abe 특별히 필요한 샘플 데이터가 무엇인지 잘 모르겠지만 원하는 결과는 없습니다. 테이블의 구조를 복제해야하지만 새 TaskID의 새 테이블이 필요합니다. 이것은 SQL Server 용입니다.

@thursdaysgeek는 상위 작업이 완료되면 모든 하위 작업도 완료된다고 가정합니다. 그리고 규칙은 루트 작업의 하위 작업이 모두 완료되면 완료 할 루트 작업을 설정할 수 있다는 것입니다. 그렇지 않으면 상위 작업이 완료되지 않았지만 하위 작업이있는 경우 하위가 아닌 상위 항목 만 복제해야합니다. 희망이 도움이됩니다.

+0

샘플 데이터와 원하는 출력을 제공 할 수 있습니까? 또한, DBMS는 어떤 용도로 사용됩니까? –

+0

완료되지 않은 하위 작업과 상위 작업이있을 수 있습니까? 그렇다면 둘 다 복제해야합니까? 부모 작업이 완전하지 않고 자식 작업이 있다면 부모 작업 만 복제해야합니까? – thursdaysgeek

+0

좋은 접근법은 이것을 C# (또는 의사 C#)로 작성하고 여기에 결과를 게시하는 것입니다. 그런 다음 해당 알고리즘을 SQL로 변환하는 데 도움을 요청하십시오. –

답변

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 

그런 다음 SQL을 실행하여 이러한 새로 삽입 된 행의 ParentId를 변경합니다. 당신이 CopiedFromTaskID을 가지고 있기 때문에이 SQL에서와 같이 새 값을 반영하기 위해 ParentID를 업데이트 할 것을 사용할 수 있습니다

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 

마지막으로, 당신은 모든 CopiedFromTaskID 값이 것 때문에 NULL하기 위해 표를 한 번 더 업데이트 당신이 그것을 실행할 때를위한 준비 :

UPDATE 
    tblTask 
SET CopiedFromTaskID = NULL 
WHERE CopiedFromTaskID IS NOT NULL 

당신은 저장 프로 시저에서 트랜잭션 내부의 모든 단계를 실행 싶어하지만, 당신이 커서/루프없이 데이터베이스 내에서 원하는 것을 수행합니다. 모든 원래 작업을 "닫으려면"SQL 문을 던져야합니다.

+0

좋은 선택 인 듯하다. Shawn, 고마워. –

+0

@shawn +1, 중첩 된 커서보다 효과적입니다. –