Pergunta

Eu tenho um banco de dados 'lista de tarefas' que utiliza o modelo de lista de adjacência (veja abaixo) para cada 'tarefa' pode ter sub-tarefas ilimitadas. A tabela tem coluna de um 'TaskOrder' assim tudo torna na ordem correta em uma árvore.

Existe uma instrução SQL (MS-SQL 2005) que irá selecionar todos os nós filho para um pai especificado e atualizar a coluna TaskOder quando um irmão é excluído?

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

Todas as idéias? Obrigado.

Foi útil?

Solução

Os pares de maneiras diferentes ... Desde o TaskOrder tem como escopo por id pai, não é terrivelmente difícil reunir-lo. No SQL Server, eu ia colocar um gatilho de exclusão que diminui todos os 'maior' do que o que você excluído, assim fechando a lacuna (pseudocódigo segue):

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

Se você não quer um gatilho, você pode capturar a parentID e TaskOrder em uma consulta primeiro, excluir a linha, em seguida, executar essa mesma instrução de atualização, mas com literais em vez do gatilho.

Ou se você quiser minimizar servidor round-trips, você pode mover a tarefa para-ser-eliminado todo o caminho até o fundo, em seguida, passar os outros para cima, em seguida, fazer a exclusão, mas que parece excessivamente complicado.

Outras dicas

Se você estiver usando apenas TaskOrder para a classificação, certamente seria mais simples simplesmente deixar os buracos em TaskOrder, porque os itens simplesmente apagar não vai fazer a incorreta classificação. Mas então eu não tenho certeza sobre as necessidades do seu aplicativo.

Não diretamente. Esta é uma topológica Ordenar onde você está 'pendurado' os nós filhos fora de um pai. Se não há nenhuma dependência nas crianças a fim de que eles são executados não importa. Se as crianças devem ser executadas em uma determinada ordem, então você não tem informação suficiente para inferir isso -. Eles teriam que ter níveis adicionais de hierarquia

Assumindo que o fim das crianças dentro de um pai é irrelevante, em seguida, uma espécie topoligical vai ter o que você quer. Você não vai conseguir isso em uma única consulta, na maioria dos dialetos SQL -. Você terá que escrever um sproc para fazê-lo

Se a ordem das crianças dentro do nó é relevante, então você precisa para manter a ordem tarefa dentro do pai. A consulta usando ParentNodeID, TaskOrder e count (*) irá escolher duplicatas mas a menos que o sistema tem informações adicionais para ordenar as tarefas que você ainda vai precisar de intervenção manual para seleccionar a ordem correta.

Por favor adicionar comentários se você quiser me esclarecer uma coisa.

Isto parece um trabalho para 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

tarefa Excluir 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;

Claro, você poderia eliminar a exclusão, e apenas deixar o registro em torno de mentir para relatar futuros propósitos.

ressalva: NÃO TESTADO !!!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top