문제

인접성 목록 모델 (아래 참조)을 사용하는 '작업 목록'데이터베이스가있어서 각 '작업'에 무제한 하위 작업이있을 수 있습니다. 테이블에는 'Taskorder'열이 있으므로 모든 것이 TreeView에서 올바른 순서로 렌더링됩니다.

지정된 부모의 모든 자식 노드를 선택하고 형제 자매가 삭제 될 때 Taskoder 열을 업데이트하는 SQL 문 (MS-SQL 2005)이 있습니까?

Task Table
----------
TaskId
ParentTaskId
TaskOrder
TaskName
--etc--

어떤 아이디어? 감사.

도움이 되었습니까?

해결책

몇 가지 다른 방법 ... Taskorder가 부모 ID에 의해 범위를 지정하기 때문에 수집하기가 크게 어렵지 않습니다. SQL Server에서는 삭제 한 것보다 '더 높은'모든 것을 줄인 삭제에 대한 트리거를 넣어 간격을 닫습니다 (Pseudocode follows).

CREATE TRIGGER ON yourtable FOR DELETE
AS
  UPDATE Task
     SET TaskOrder    = TaskOrder - 1
   WHERE ParentTaskId = deleted.ParentTaskId
     AND TaskOrder    > deleted.TaskOrder

트리거를 원하지 않으면 먼저 쿼리에서 Parentid와 Taskorder를 캡처 한 다음 행을 삭제 한 다음 동일한 업데이트 문을 실행하지만 트리거가 아닌 리터럴로 실행할 수 있습니다.

또는 서버 왕복 트립을 최소화하려면 삭제 된 작업을 바닥으로 끝까지 이동 한 다음 다른 것을 위로 올린 다음 삭제를 수행 할 수 있지만 지나치게 복잡해 보입니다.

다른 팁

정렬을 위해 TaskOrder 만 사용하는 경우 항목을 삭제하는 것이 정렬을 잘못 만들지 않기 때문에 TaskOrder에 구멍을 남기는 것이 더 간단합니다. 그러나 귀하의 응용 프로그램의 요구에 대해 잘 모르겠습니다.

직접적이지 않습니다. 이것은 토폴로지 정렬 어린이가 부모에게 노드를 '매달아'하는 곳. 어린이 내에 의존성이없는 경우 처형 된 순서는 중요하지 않습니다. 어린이가 특정 순서로 처형되어야한다면이를 추론하기에 충분한 정보가 없으므로 추가 수준의 계층 구조가 있어야합니다.

부모 내의 어린이의 순서가 관련이 없다고 가정하면 토폴리치 종류는 당신이 원하는 것을 얻을 수 있습니다. 대부분의 SQL 방언에서 이것을 단일 쿼리로 가져 가지 않을 것입니다.

노드 내 어린이의 순서가 관련이있는 경우 부모 내에서 작업 순서를 유지해야합니다. ParentNodeid, Taskorder 및 Count (*)를 사용하는 쿼리는 복제물을 선택하지만 시스템에 작업을 주문하기위한 추가 정보가 없으면 올바른 순서를 선택하려면 수동 개입이 필요합니다.

내가 무언가를 명확히하기를 원한다면 의견을 추가하십시오.

이것은 row_number의 직업처럼 보입니다.

DECLARE @Tasks TABLE
(
  TaskId int PRIMARY KEY,
  ParentTaskId int,
  TaskOrder int,
  TaskName varchar(30)
)

INSERT INTO @Tasks(TaskId, ParentTaskId, TaskOrder, TaskName)
SELECT 1, null, 1, 'ParentTask'

INSERT INTO @Tasks(TaskId, ParentTaskId, TaskOrder, TaskName)
SELECT 2, 1, 2, 'B'

INSERT INTO @Tasks(TaskId, ParentTaskId, TaskOrder, TaskName)
SELECT 3, 1, 1, 'A'

INSERT INTO @Tasks(TaskId, ParentTaskId, TaskOrder, TaskName)
SELECT 4, 1, 3, 'C'
--Initial
SELECT * FROM @Tasks WHERE ParentTaskId = 1 ORDER BY TaskOrder

DELETE FROM @Tasks WHERE TaskId = 2
--After Delete
SELECT * FROM @Tasks WHERE ParentTaskId = 1 ORDER BY TaskOrder


UPDATE t
SET TaskOrder = NewTaskOrder
FROM @Tasks t
  JOIN
(
SELECT TaskId, ROW_Number() OVER(ORDER BY TaskOrder) as NewTaskOrder
FROM @Tasks
WHERE ParentTaskId = 1
) sub ON t.TaskId = sub.TaskId

--After Update
SELECT * FROM @Tasks WHERE ParentTaskId = 1 ORDER BY TaskOrder

작업 삭제 88 :

UPDATE TaskTable
SET ParentTaskID = (SELECT ParentTaskID AS temp FROM Task_Table t1 WHERE TaskID = 88)
WHERE
TaskID IN (SELECT TaskID task2 FROM TaskTable t2 WHERE ParentTaskID = 88);
Delete FROM TaskTable WHERE TaskID = 88;

물론 삭제를 제거하고 향후보고 목적으로 기록을 놓을 수 있습니다.

경고 : 테스트되지 않았습니다 !!!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top