Autor Beitrag
Nightfly
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 163



BeitragVerfasst: Fr 26.09.03 10:32 
Hi

Ich möchte meine Datenbank als Baum darstellen (und dann später auch mal einträge hinzifügen u.s.w.)..bloß leider komm ich jetzt nich weiter :(
Meine Tabelle besteht aus 2 Feldern, der Bezeichnung (das soll im Baum angezeigt werden) und einem Key für jeden Datensatz.

Dieser Key realisiert die BAumstruktur, und Zwar wie Folgt:
0 ist der root
01,02,03, ..sind die elemente des ersten levels, ihr Parent ist 0,also root

010,011,012,013 sind demzufolge von 0 bis 3 durchnummerierte Kinder von 01 ..u.s.w., ich denke ein einfaches System.
Bloß wie bekomme ich das jetzt in einen Baum?

Root is ja kein Problem, einfach FindKey([0]) und ab damit als root in den Baum.
So,nun ist der Root mein aktueller Knoten,also kann ich auch alle Level1 teile drunter schreiben..einfach durch die DAtenbank gehen, und wenn (length(key)=2) dann ab damit als Child unter Root

So, und dann verließen sie ih :( Kann mir ab hier jemand weiter helfen, bitte? Ein hauptproblem: kann ich sagen "gehe zu knoten 02" also ein Level 1 knoten, mitten im Baum?
UGrohne
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Fr 26.09.03 10:40 
Kein Problem, aber lass das erste Feld einfach als Primary, mach ein weiteres Feld dazu (named root), das den Eltern-Datensatz anzeigt und schau in diesem Thread wie's weitergeht, da hab ich weiter unten kompletten Code mit Stored Procedure usw gepostet ;-)
Nightfly Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 163



BeitragVerfasst: Fr 26.09.03 10:43 
Noch ist mir der Sinn eines neuen feldes zwar unklar, weil aus meinem "key" feld is der parent ja ersichtlich, wenn ich die letzte Ziffer abschneide (also key 01002 hat demzufolge als parent datensatz 0100)

ABer ich werd mich da mal reindenken, danke erstmal..
UGrohne
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Fr 26.09.03 10:50 
Ja, ok, es ist schon eine Möglichkeit, aber das Problem ist dann die Stored Procedure, dürfte schwierig sein, das Feld da zu zerpflücken. Ich wollte halt nicht alles im Programm selber machen, soviel wie möglich auf die Datenbank auslagern ;-)
Nightfly Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 163



BeitragVerfasst: Fr 26.09.03 10:58 
Gut, das sehe ich mittlerweile ein. Jeder Datenbank Theoretiker stöhnt zwar bei dem Gedanken an die Redundanz, aber sei's drum...die paar bytes ham 'wir auch noch.
Zwei probleme: der C Code sagt mir leider so gut wie nix :oops: ...und StoredProcedures...keinen schimmer was das is..obwhol ich den Code einigermaßen zu verstehen glaube. Aber was sind StoredProcedures? Ja, es gibt ja ne Delphi Kompo dafür. Ich weiß glaub ich das die Dinger schon irgendwie direkt an der DB rumzaubern..sogar auf dem Server. Ich verwende den local Advantage Database Server...wo muß jetzt die stored Pocedure hin..is das 'n extra file..oder in die betreffende Datei..help plz :oops:
UGrohne
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Fr 26.09.03 11:05 
Oh, das hab ich antürlich vergessen zu fragen. Die Stored Procedure ist für Interbase, ich weiß net wie das bei ADS ist, da muss wohl dann jemand doch anders ran.

SPs werden direkt auf dem Server ausgeführt, das vermindert die Datenübertragung und ist demnach meist auch schneller, vor allem müssen teilweise direkt auf der DB weniger Abfragen gemacht werden, als wenn alles auf dem Client läuft.

Und als Redundanz empfinde ich das net so richtig, es ist eher einfach leichter und schneller mit einem weiteren Feld, da String-Operationen ja nicht die schnellsten sind. Eigentlich hast Du Redundanz, da Du bei jedem Kind den kompletten Stammbaum bis zum Ahne drin hast.
Nightfly Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 163



BeitragVerfasst: Fr 26.09.03 11:09 
hmmm..damit haste natürlich auch wieder recht...naja, aber heutzutage brauch man sich bei so kleinen Projekten wie dem hier wohl keine Gedanken mehr über Platzverschwendung machen..und deine Version is zweifelsohne leichter zu handhaben.
Nightfly Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 163



BeitragVerfasst: Fr 26.09.03 11:38 
Mal noch ne ganz blöde Frage: Wie kann ich direkt auf einen Knoten zugreifen? Unter Umständen wäre es machbar das die Knoten eindeutige Bezeichnungen Tragen..wie "geht" man normalerweise durch den Baum?
Nightfly Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 163



BeitragVerfasst: Fr 26.09.03 13:35 
So, folgendes hab ich gemacht. Nicht schön, aber es funktioniert.

Zuerst eine Hilfsfunktion, um den Baum zu durchsuchen:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
Function TreeViewItemSearch (aInTreeView: tTreeView; aSearchText: String): tTreeNode;
Var
  Loop: Integer;
Begin
  Result := nil;

  If Not Assigned (aInTreeView) or (aSearchText = '') Then
    Exit;

  For Loop := 0 To aInTreeView.Items.Count - 1 Do
    If aSearchText = aInTreeView.Items[Loop].Text Then
      Begin
        Result := aInTreeView.Items[Loop];
        Break;
      End
End;


Und dann meine Funktion zum Datensatz eintragen:

ausblenden volle Höhe Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
procedure TForm1.Button4Click(Sender: TObject);
Var
anzahl,check : integer;
sText,parent        : string;
Knoten       : TTreeNode;
begin
anzahl := 1000;
sText := '01';
check := 0;

       if Table1.FindKey(['0'])then
                                 begin                                                      //Root anlegen
                                  with TreeView1.Items.AddFirst(  nil,  Table1Key.Value  ) do
                                    begin
                                     Selected := true;
                                  end;
                                 end
                               else Application.MessageBox('Kein Wurzelknoten gefunden','LC Fehler',MB_OK);
       repeat

           if Table1.FindKey([sText]) then
                                            begin
                                            parent := Copy(sText,0,(length(sText)-1));
                                            Knoten := TreeViewItemSearch(TreeView1,parent);
                                            TreeView1.Items.AddChild(  Knoten,Table1Key.Value);
                                            end;

           sText := StrInc(SText);
         anzahl := anzahl-1;
        until anzahl = 1;


end;


So...nun folgendes Problem: Im Baum sind halt noch meine Key's eingetragen, also 01, 011 u.s.w. Also müßte ich jetzt nochmal durch den Tree laufen, und jeden Key seinen Bezeichner Zuordnen. :(
Viel besser würde mir gefallen wenn ich das Identifizieren der Knoten statt über die Text Eigenschaft über die Data Eigenschaft machen. Aber das sind ja Zeiger..kann mir einer helfen?
UGrohne
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Fr 26.09.03 15:48 
In der Online-Hilfe unter Data hat es ein super Beispiel, danach hab ich das auch im C++-Builder gemacht, war kein Problem. Eigentlich nur abschreiben.