9 Stimmen

Ist Rekursion in SQL Server gut?

Ich habe eine Tabelle in SQL Server, die die normale Baumstruktur von Item_ID, Item_ParentID hat. Angenommen, ich möchte alle KINDER eines bestimmten Item_ID (auf jeder Ebene) durchlaufen und abrufen.

Rekursion scheint ein intuitiver Kandidat für dieses Problem zu sein, und ich kann eine SQL Server-Funktion schreiben, um dies zu tun.

Wird sich die Leistung beeinträchtigen, wenn meine Tabelle sehr viele Datensätze enthält? Wie kann ich Rekursion vermeiden und einfach die Tabelle abfragen? Bitte um Vorschläge?

0voto

JosephStyons Punkte 55410

Vielleicht wäre etwas mehr Detail angebracht.

Wenn Sie eine Master-Detail-Beziehung haben, wie Sie beschreiben, reicht dann nicht ein einfacher JOIN aus, um das zu erhalten, was Sie brauchen?

Wie zum Beispiel:

SELECT
  EINIGE_FELDER
FROM
  MASTER_TABELLE MT
 ,CHILD_TABELLE CT
WHERE CT.PARENT_ID = MT.ITEM_ID

0voto

Keith Punkte 141163

Du solltest keine Rekursion für Kinder benötigen - du betrachtest nur die Ebene direkt darunter (d.h. select * from T where ParentId = ) - du benötigst Rekursion nur für alle Nachkommen.

In SQL2005 kannst du die Nachkommen mit folgendem bekommen:

with AllDescendants (ItemId, ItemText) as (
    select t.ItemId, t.ItemText 
        from [TableName] t
    where t.ItemId = @ancestorId
    union
    select sub.ItemId, sub.ItemText 
        from [TableName] sub
            inner join [TableName] tree
            on tree.ItemId = sub.ParentItemId
)

0voto

Cervo Punkte 3132

Sie brauchen überhaupt keine Rekursion.... Hinweis: Ich habe die Spalten in ItemID und ItemParentID geändert, um das Tippen zu erleichtern...

DECLARE @intLevel INT
SET @intLevel = 1

INSERT INTO TempTable(ItemID, ItemParentID, Level)
SELECT ItemID, ItemParentID, @intLevel
WHERE ItemParentID IS NULL

WHILE @intLevel < @TargetLevel
BEGIN
     SET @intLevel = @intLevel + 1
     INSERT INTO TempTable(ItemID, ItemParentID, Level)
          SELECt ItemID, ItemParentID, @intLevel
          WHERE ItemParentID IN (SELECT ItemID FROM TempTable WHERE Level = @intLevel-1)
     -- If no rows are inserted then there are no children
     IF @@ROWCOUNT = 0
       BREAK
END

SELECt ItemID FROM TempTable WHERE Level = @TargetLevel

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X