Frage

Ich habe eine ‚Aufgabenliste‘ Datenbank für Sie, Adjazenzliste Modell (siehe unten), so dass jede ‚Aufgabe‘ verwendet unbegrenzte Teilaufgaben haben. Der Tisch hat eine ‚Taskorder‘ Spalt so alles in der richtigen Reihenfolge auf einem treeview macht.

Gibt es eine SQL-Anweisung (MS-SQL 2005), die alle untergeordneten Knoten für eine bestimmte Mutter wählen werden und die TaskOder Spalte aktualisieren, wenn ein Geschwister gelöscht?

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

Irgendwelche Ideen? Danke.

War es hilfreich?

Lösung

Ein paar verschiedene Arten ... Da die Taskorder von Eltern-ID scoped ist, ist es nicht sehr schwierig, sie zu sammeln. In SQL Server, würde ich einen Trigger auf löschen setzen, dass alle diejenigen, dekrementiert ‚höher‘ als das von Ihnen gelöscht, wodurch die Lücke (Pseudo-Code folgt):

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

Wenn Sie keinen Trigger wollen, können Sie die parentID und Taskorder in einer Abfrage zuerst erfassen, löschen Sie die Zeile, und führen Sie dann das gleiche Update-Anweisung aber mit Literale statt der Auslöser.

Oder wenn Sie Server Roundtrips minimieren möchten, können Sie die zu-Lösch Aufgabe den ganzen Weg nach unten bewegen, dann die anderen nach oben, dann die Lösch tun, aber das scheint zu kompliziert.

Andere Tipps

Wenn Sie nur Taskorder für die Sortierung verwendet wird, wäre es sicherlich einfacher sein, einfach die Löcher in Taskorder zu verlassen, weil einfach Löschen von Elementen nicht die Sortierung falsch machen. Aber dann bin ich nicht sicher über die Notwendigkeiten der Anwendung.

Nicht direkt. Dies ist ein topologische Sortierung wo Sie eine übergeordnete ‚hängen‘ die untergeordneten Knoten aus sind. Wenn es keine Abhängigkeit innerhalb der Kinder ist die Reihenfolge, dass sie ausgeführt werden spielt keine Rolle. Wenn die Kinder müssen in einer bestimmten Reihenfolge ausgeführt werden dann müssen Sie nicht genug Informationen, diese zu schließen -. Sie müssten zusätzliche Hierarchieebenen haben

Unter der Annahme,

, dass die Reihenfolge der Kinder innerhalb eines übergeordneten irrelevant ist dann ein topoligical Art erhalten Sie, was Sie wollen. Sie werden dies nicht eine einzelne Abfrage in den meisten SQL-Dialekte erhalten in -. Sie sproc schreiben müssen es tun

Wenn die Reihenfolge der Kinder innerhalb des Knotens relevant ist, dann müssen Sie die Aufgabe, um innerhalb der übergeordneten zu halten. Eine Abfrage mit ParentNodeID, Taskorder und count (*) werden Duplikate auswählen, aber es sei denn, das System verfügt über zusätzliche Informationen, um die Aufgaben zu bestellen, erhalten Sie noch manuelle Eingriffe müssen die richtige Reihenfolge wählen.

Bitte kommentieren, wenn Sie wollen, dass ich etwas klären.

Das sieht wie ein Job für 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

Löschen Aufgabe 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;

Natürlich können Sie die Lösch beseitigen könnten, und lassen Sie nur den Rekord um für zukünftige Berichterstattung liegen.

CAVEAT: nicht geprüft !!!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top