Question

J'ai une base de données "liste de tâches" qui utilise le modèle de liste de contiguïté (voir ci-dessous) afin que chaque "tâche" puisse avoir un nombre illimité de sous-tâches. La table contient une colonne "TaskOrder" afin que tout soit restitué dans le bon ordre dans un arbre.

Existe-t-il une instruction SQL (MS-SQL 2005) qui sélectionne tous les nœuds enfants d'un parent spécifié et met à jour la colonne TaskOder lorsqu'un frère est supprimé?

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

Des idées? Merci.

Était-ce utile?

La solution

Deux façons différentes ... Puisque TaskOrder est défini par son identifiant, il n’est pas très difficile de le rassembler. Dans SQL Server, je mettrais un déclencheur à la suppression qui décrémenterait tous ceux "plus élevés" que celui que vous avez supprimé, ce qui réduirait l'écart (le pseudocode suit):

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

Si vous ne voulez pas de déclencheur, vous pouvez d'abord capturer le parentID et le TaskOrder dans une requête, supprimer la ligne, puis exécuter la même instruction de mise à jour, mais avec des littéraux plutôt que le déclencheur.

Ou si vous souhaitez réduire les allers-retours du serveur, vous pouvez déplacer la tâche à supprimer de tout en bas, puis déplacer les autres tâches vers le haut, puis supprimer, mais cela semble trop compliqué.

Autres conseils

Si vous utilisez uniquement TaskOrder pour le tri, il serait certainement plus simple de simplement laisser les trous dans TaskOrder, car la suppression d'éléments ne rendra pas le tri incorrect. Mais je ne suis pas sûr des besoins de votre application.

Pas directement. Il s’agit d’un Tri topologique dans lequel vous "pendez" les nœuds enfants d'un parent. S'il n'y a pas de dépendance chez les enfants, l'ordre d'exécution est sans importance. Si les enfants doivent être exécutés dans un certain ordre, vous ne disposez pas de suffisamment d'informations pour le déduire. Ils doivent disposer de niveaux de hiérarchie supplémentaires.

En supposant que l'ordre des enfants au sein d'un parent ne soit pas pertinent, une sorte de topologie vous donnera ce que vous voulez. Cela ne se retrouvera pas dans une requête unique dans la plupart des dialectes SQL - vous devrez écrire un sproc pour le faire.

Si l'ordre des enfants dans le nœud est pertinent, vous devez conserver l'ordre des tâches dans le parent. Une requête utilisant ParentNodeID, TaskOrder et count (*) identifiera les doublons, mais à moins que le système ne dispose d'informations supplémentaires pour ordonner les tâches, vous aurez toujours besoin d'une intervention manuelle pour sélectionner le bon ordre.

Ajoutez des commentaires si vous souhaitez que je clarifie quelque chose.

Cela ressemble à un travail pour 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

Supprimer la tâche 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;

Bien sûr, vous pouvez supprimer la suppression et laisser le dossier traîner pour de futurs rapports.

CAVEAT: NON TESTÉ !!!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top