![]() |
Datenbank: MSSQL • Version: 2000 • Zugriff über: ADO
MSSQL - Problem mit Rekursiver SP
Moin
Ich habe ein kleines Problem mit einer Rekursion und zwar muss ich eine TreeView aus einer Datenbank erstellen, mit ID, ParentID etc. Ihr kennt das bestimmt. Um die Nodes in geordneter Reihenfolge aus der Datenbank zu bekommen, habe ich die Stored Procedure von Omata ( ![]() Im Grunde funktioniert das ganz gut, nur bei tiefen Bäumen (Vlt. so ab 12, weiss es nicht mehr genau) bekomme ich nur noch 2 leere Nodes und dann ist schluss. Wenn ich die Stored Procedure allerdings im Query Analyzer aufrufe, zeigt es mir alle Nodes mit ihren IDs und Parent IDS sowie dem Level an. :gruebel: Verstehen tu ich es nicht, aber da alzaimar geschrieben hat, dass diese Lösung bei tiefen Bäumen versagt, glaube ich das einfach mal. Die Frage ist, wie ich das nun lösen soll. Es gibt da eine DBTreeView Komponente, allerdings kann ich da keinen Record benutzen um Daten für jeden Node abzuspeichern (oder besser gesagt, ich wüsste nicht wie). Wie würdet ihr das ganze sauber und performant und nicht zu kompliziert lösen, wenn ihr von Delphi 9, MSSQL 2000, der VirtualTreeView Komponente und der Datenbank mit ID, PID und Bezeichnung ausgeht? Hoffe jemand kann mir helfen und viele Grüsse Siles |
Re: MSSQL - Problem mit Rekursiver SP
Zitat:
Zusätzlich gibt man noch den Feldnamen an, den das DBTreeView als Knotennamen anzeigen soll. Wenn man einen bestimmten Knoten selektiert hat, steht der aktuelle Datensatzzeiger genau auf diesem Datensatz. Nun ist es kein Problem, über weitere DBEdit-Felder auf dem Formular diese Datenfelder anzuzeigen und auch editierbar zu machen. |
Re: MSSQL - Problem mit Rekursiver SP
Zitat:
Bei der normalen VirtualTreeView konnte man einen Record anlegen und so mehrere Daten einem Node zuweisen, ich weiss nicht wie das damit gehen soll weil ja nur die Namen der DB Felder: ID, PID, ChildrenId und Name als Eigenschaften angegeben werden können. |
Re: MSSQL - Problem mit Rekursiver SP
Zitat:
Wie oben gesagt, wenn du im DBTreeView einen bestehenden Knoten anklickst, da steht das Dataset genau auf diesem Datensatz. Das DBTreeView übernimmt hier die Aufgabe eines DBNavigators. Das Ändern von Daten geht dann so:
Delphi-Quellcode:
Das Löschen des aktuellen Knotens ist auch einfach:
Query1.Edit;
Query1['User'] := aktuellerUser; Query1['LastChange'] := Now; Query1.Post;
Delphi-Quellcode:
Das Einfügen eines neuen Kindknoten ist etwas schwieriger, weil man dazu eine neue ID benötigt.
query1.Delete;
Mit folgender SQL-Abfrage kann man sich diese ID besorgen.
SQL-Code:
Zusätzlich benötigt man noch die ParendID - diese lässt sich höchstwahrscheinlich über das DBTreeView erhalten
SELECT Max(ID)+1 AS NewID FROM Tabelle
; das Property könnte ParentValue oder so ähnlich heisen. (dieses Property ist readonly und deshalb im OI unsichtbar) |
Re: MSSQL - Problem mit Rekursiver SP
Zitat:
Wenn das so ist könnte ich diese vermutlich doch verwenden! Ich schaue mir es nochmals genauer an - morgen. Vielen herzlichen Dank schonmal! :thumb: |
Re: MSSQL - Problem mit Rekursiver SP
Hallo siles,
schau auch mal ![]() Edit: Ups, du hattest ja den Link oben angegeben. Schau dir aber dort trotzdem mal den Post #5 an. Gruss Thorsten |
Re: MSSQL - Problem mit Rekursiver SP
Zitat:
Die Stored Procedure aus Post 5 habe ich heute auch schon auf meine Anwendung angepasst und erstellt, ich bekomme dann beim ausführen der SP mit der PID als Argument alle ihm untergeordneten Nodes (Childs) zurück. Ich habe es leider nicht fertig gebracht, diese dann in die TreeView zu bringen, hatte jedesmal ein Blackout wenn ich mich in die Sache eindenken wollte :( Ich könnte mir denken, ich müsste erst mal in nem Query alle Notes auf Root abfragen und für jeden davon die Storedprocedure ausführen um alle ihre Subnodes und Sub-Subnodes etc. herauszubekommen. Dann stösst es jedoch schon an. Wie ich diese dann mit welchen Schleifen in die TreeView befordere ist mir irgendwie grad zu kompliziert :( |
Re: MSSQL - Problem mit Rekursiver SP
Hier mal ein Beispiel...
Delphi-Quellcode:
Aufruf...
procedure fillTreeview(Tree:TTreeview; SQLConnection:TSQLConnection);
procedure fill(Depth:integer; ANode:TTreeNode; SDS:TSimpleDataSet); var abbruch:boolean; Node:TTreeNode; begin abbruch:=false; while not SDS.Eof and not abbruch do begin Node:=Tree.Items.AddChild( ANode, SDS.FieldByName('nodename').AsString ); SDS.Next; if SDS.FieldByName('depth').AsInteger > Depth then fill(Depth+1, Node, SDS); if SDS.FieldByName('depth').AsInteger < Depth then abbruch:=true; end; end; var SDS:TSimpleDataSet; begin SDS:=TSimpleDataSet.Create(nil); try Tree.Items.BeginUpdate; Tree.Items.Clear; SDS.Connection:=SQLConnection; SDS.DataSet.CommandType:=ctStoredProc; SDS.DataSet.CommandText:= 'GetSortedSubTree'; SDS.DataSet.ParamByName('nodeid').AsInteger:=1; SDS.Open; fill(SDS.FieldByName('depth').AsInteger, nil, SDS); SDS.Close; finally SDS.free; Tree.Items.EndUpdate; end; end;
Delphi-Quellcode:
Gruss
fillTreeview(TreeView, SQLConnection);
Thorsten |
Re: MSSQL - Problem mit Rekursiver SP
Zitat:
Ach ja etwas musste ich andes machen und zwar konnte ich nicht die DBExpress Komponenten verwenden..das SimpleDataSet meldet einen Fehler wegen des Cursors. Habe stattdessen die Ado Komponenten benutzt und diese direkt im GUI erstellt und nicht im Code. Denke aber nicht dass das etwas ausmacht. |
Re: MSSQL - Problem mit Rekursiver SP
Liste der Anhänge anzeigen (Anzahl: 1)
Hier mal ein Beispiel mit ADO...
Delphi-Quellcode:
Gruss
procedure fillTreeview(Tree:TTreeview; ADOConnection:TADOConnection);
procedure fill(Depth:integer; ANode:TTreeNode; ADOStoredProc:TADOStoredProc); var abbruch:boolean; Node:TTreeNode; begin abbruch:=false; while not ADOStoredProc.Eof and not abbruch do begin Node:=Tree.Items.AddChild( ANode, ADOStoredProc.FieldByName('nodename').AsString ); ADOStoredProc.Next; if ADOStoredProc.FieldByName('depth').AsInteger > Depth then fill(Depth+1, Node, ADOStoredProc); if ADOStoredProc.FieldByName('depth').AsInteger < Depth then abbruch:=true; end; end; var ADOStoredProc:TADOStoredProc; begin ADOStoredProc:=TADOStoredProc.Create(nil); try Tree.Items.BeginUpdate; Tree.Items.Clear; ADOStoredProc.Connection:=ADOConnection; ADOStoredProc.ProcedureName:='GetSortedSubTree;1'; ADOStoredProc.Parameters.Refresh; ADOStoredProc.Parameters.ParamByName('@NodeID').Value:=1; ADOStoredProc.Open; fill(ADOStoredProc.FieldByName('depth').AsInteger, nil, ADOStoredProc); ADOStoredProc.Close; finally ADOStoredProc.free; Tree.Items.EndUpdate; end; end; Thorsten |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:07 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz