Das ist ok, dauert aber zu lange und versagt bei tiefen Bäumen.
Nimm folgenden Ansatz:
1. Am Anfang enthält die Resultatmenge genau eine Zeile 'ID' und 'ParentID' des Knotens, dessen Unterbaum geliefert werden soll
2. Solange die Resultatmenge noch nicht abgearbeitet ist (Ja, ein Cursor)
2.1 Füge ALLE Knoten der Baumtabelle in die Resultatmenge mit ID = CurrentParentID
2.2 Gehe zum nächsten Eintrag der Resultatmenge
Mit jedem Durchlauf wächst die Resultatmenge also, bis eben keine Blätter mehr gefunden werden
SQL-Code:
Create Procedure ListSubTree @ID int
as
set nocount on
declare @ChildID int,
declare @Table Table (
ID INT,
ParentID INT,
Bezeichnung VARCHAR(1000)
)
-- 1.Zeile in die Tabelle
--
insert into @Table
select @ID, ParentID from TreeTable where ID = @ID
Declare c Cursor local for select ID from @Table
open c
fetch next from c into @ChildID
while @@Fetch_status = 0 begin
--
-- Mit jedem Schleifendurchlauf werden in einem Abwasch ALLE Kindknoten eingefügt
--
insert into @Table
select ID,ParentID from TreeTable where ParentID = @ChildID
fetch next from c into @ChildID
end
close c
deallocate c
set nocount off
select * from @Table
Ich liefere noch den ParentNode aller Einträge, damit der Baum auch aufgebaut werden kann. Wenn man vorher noch einen Clustered Index auf die ParentID legt, und @Table nach dieser Spalte sortiert zurückliefert, kann man den Baum in linearer Zeit in einer TTreeView konstruieren und muss nicht für jeden Knoten den Elternknoten suchen. Das ist bei sehr großen Bäumen durchaus nützlich.
Das sollte funktionieren, ist aber nicht getestet. Table-Variablen funktionieren ab MSDE2000. Mit der 2005'er kann man auch rekursive Joins machen, die hab ich aber nicht. Es gibt darüber einen Artikel auf
www.sqlcentral.com (sowieso ganz nett, die Site).
[EDIT] Nochwas:
SQL ist mengenbasiert, denke also immer in Mengen, nie in Records! [/EDIT]