| Autor |
Beitrag |
cyberax
      
Beiträge: 247
Win XP Pro
Delphi 5 Enterprise
|
Verfasst: Sa 13.10.07 17:29
Hallo,
ich habe eine Tabelle, deren Struktur ich in einem Treeview darstellen möchte. Funktioniert auch einwandfrei, bis auf die Geschwindigkeit beim Aufbau der Struktur.
Der Treeview wird wie folgt erstellt...
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| with ZQuery1 do begin sql.text:='Select * from gruppe'; open; end; FieldList := TStringList.create; TreeView1.items.BeginUpdate; ZQuery1.first; while not ZQuery1.eof do begin TreeAddItem(TreeView1, GetFieldList, ZQuery1.getBookmark, false); ZQuery1.next; end; FieldList.clear; TreeView1.Alphasort; TreeView1.items.Endupdate; |
und hier die Funktion Getfieldlist...
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: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43:
| function Tonline_tree.GetFieldList: TStringList; var akt_gruppe:integer; i,j:integer; begin FieldList.clear; with online_tree.ZQuery2 do begin sql.Text:='SELECT * FROM gruppe WHERE ID = :GRUPPE'; With Params.ParamByName('GRUPPE') do begin DataType := ftinteger; Value := online_tree.ZQuery1.fieldbyname('GR_ID').asinteger; End; open; end; if ZQuery2.RecordCount>0 then if ZQuery2.FieldByName('gr_id').asinteger > 0 then begin repeat FieldList.add(ZQuery2.fieldbyname('NAME').asstring); akt_gruppe:=zQuery2.fieldbyname('gr_id').AsInteger; with online_tree.ZQuery2 do begin sql.Text:='SELECT * FROM gruppe WHERE ID = :GRUPPE'; With Params.ParamByName('GRUPPE') do begin DataType := ftinteger; Value := akt_gruppe; End; open; end; until akt_gruppe=0; i:= 0; j := FieldList.count-1; while i<j do begin FieldList.Exchange(I,J); inc(i); dec(j) end; end else repeat FieldList.add(ZQuery2.fieldbyname('NAME').asstring); until ZQuery2.FindNext=false; FieldList.add(ZQuery1.fieldbyname('NAME').asstring); Result := FieldList; end; |
Die Tabelle Gruppe sieht so aus:
id Integer(5)
gr_id Integer(5)
name varchar(255)
...
Offline merkt man nichts, aber wenn die DB online liegt und die Tabelle paar Datensätze (300 oder mehr) hat die tief verzeweigt sind (vom Treeview her gesehen), dann dauert es ewig.
habt ihr ne Idee, wie ich das besser/schneller lösen kann?
Gruß cyberax
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Sa 13.10.07 22:49
Was für deinen Fall wahrscheinlich das sinnvollste wäre, wäre die Nutzung von rekursiven SELECTs, wie diese in Oracle mit CONNECT BY\START WITH bereitgestellt werden. Das das aber AFAIK kein standard-SQL nach ANSI ist, implementiert das jede DB anders (wenn überhaupt.
Eine mögliche Lösung, auf die mich ein Foren-Beitrag gebracht hat, wäre die Nutzung von Stored Procedures, was jedoch auf jeden Fall MySQL5 voraussetzen würde (IIRC).
Inwiefern sich das Problemlos nach MySQL übersetzen lässt, weiß ich grad nicht.
Ein wenig Suche ergab aber diesen Thread wo Du in dieser Antwort eine recht ausführliche Auflistung von Möglichkeiten, u.a. mit diesem Beispiel findest.
HTH.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
cyberax 
      
Beiträge: 247
Win XP Pro
Delphi 5 Enterprise
|
Verfasst: So 14.10.07 09:53
Dank dir erstmal. Das hat mir schonmal paar neue Anregungen für meine Problemlösung gegeben.
|
|
cyberax 
      
Beiträge: 247
Win XP Pro
Delphi 5 Enterprise
|
Verfasst: So 14.10.07 11:17
Also der Aufbau des Tree funktioniert soweit einwandfrei...
Delphi-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:
| with ZQuery1 do begin sql.Text:='SELECT t1.name, t1.id, t1.gr_id, t1.bild, t1.artikel_id, t1.kategorie, t1.name AS lev1, t2.name AS lev2, t3.name AS lev3, t4.name AS lev4,t5.name AS lev5 '+ 'FROM gruppe AS t1 '+ 'LEFT JOIN gruppe AS t2 ON t2.gr_id = t1.id '+ 'LEFT JOIN gruppe AS t3 ON t3.gr_id = t2.id '+ 'LEFT JOIN gruppe AS t4 ON t4.gr_id = t3.id '+ 'LEFT JOIN gruppe AS t5 ON t4.gr_id = t4.id '+ 'WHERE t1.gr_id = :wert'; parambyname('wert').asinteger:=0; open; end;
FieldList := TStringList.create; TreeView1.items.BeginUpdate; ZQuery1.first; while not ZQuery1.eof do begin fieldlist.Clear; fieldlist.add(ZQuery1.fieldbyname('lev1').asstring); if ZQuery1.fieldbyname('lev2').asstring<>''then fieldlist.add(ZQuery1.fieldbyname('lev2').asstring); if ZQuery1.fieldbyname('lev3').asstring<>''then fieldlist.add(ZQuery1.fieldbyname('lev3').asstring); if ZQuery1.fieldbyname('lev4').asstring<>''then fieldlist.add(ZQuery1.fieldbyname('lev4').asstring); if ZQuery1.fieldbyname('lev5').asstring<>''then fieldlist.add(ZQuery1.fieldbyname('lev5').asstring); TreeAddItem(TreeView1, fieldlist, ZQuery1.getBookmark, false); ZQuery1.next; end; |
habe nun aber folgendes problem:
In Treeview.onchange stand bei mir immmer:
Delphi-Quelltext 1:
| if DataSource1.enabled then ZQuery1.gotobookmark(node.Data); |
um zum aktuellen Datensatz zu springen. Funktioniert ja auch, aber wie werden kann ich nun ohne weitere Queries relisieren, dass mit dann z.B. bei dem Edit Feld für "name" der wirkliche Name angezeigt wird.
Bsp zur Erklärung:
Quelltext 1: 2: 3: 4: 5: 6:
| Autos - groß - klein - sehr klein
Fahrräder -> |
WEnn ich nun zum Datensatz "sehr klein" spring, zeigt mir das Editfeld natürlich "Autos" an. Ich brauch aber "sehr klein" mit dazugehörigen weiteren Werten, damit ich diese editieren kann.
Muss meine Abfrage anders aussehen???
Gruß cyberax
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: So 14.10.07 19:22
Der jeweils zu verwendende Wert den Du als Name haben willst, steht immer in der Tabellenspalte, die als letzte keinen NULL-Wert enthält.
D.h. Bei Auto in Spalte 1, bei klein in Spalte 2 und bei sehr klein in Spalte 3.
Schau Dir ggf. einmal die auf dev.mysql.com gezeigte Lösung mit den Left\Right-Werten an. Dort kannst Du sowohl das Level eines Eintrages, als auch dessen Name ohne solche Umwege anzeigen. Nachteil ist aber, dass eine zusätzliche Datenverwaltung notwendig wird.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
cyberax 
      
Beiträge: 247
Win XP Pro
Delphi 5 Enterprise
|
Verfasst: So 14.10.07 19:57
| Zitat: | Der jeweils zu verwendende Wert den Du als Name haben willst, steht immer in der Tabellenspalte, die als letzte keinen NULL-Wert enthält.
|
Ja so ähnlich hatte ich's auch inzwischen gelöst:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| ZQuery1.gotobookmark(node.Data); if node.text = ZQuery1.fieldbyname('lev1').asstring then begin dbedit1.dataField:='gr_id'; dbedit3.dataField:='name'; dbtext1.dataField:='id'; dbedit2.dataField:='bild'; dbedit4.dataField:='artikel_id'; DBCheckBox1.dataField:='kategorie'; end; if node.text = ZQuery1.fieldbyname('lev2').asstring then begin dbedit1.dataField:='gr_id2'; dbedit2.dataField:='bild2'; dbedit3.dataField:='n2'; dbtext1.dataField:='id2'; dbedit4.dataField:='artid2'; DBCheckBox1.dataField:='kat2'; end; ... |
nur komischerweise funktioniert das nur, wenn ich eine Verzweigung schonmal geöffnet habe.
Sprich - wenn ich (um beim obigen Beispiel zu bleiben) auf "Autos" klicke (im Treeview), dann habe ich keinen Rückgabewert (node.data). Wenn ich aber die Strucktur/Verzweigung einmal geöffnet und untere Zweige angeklickt habe, dann habe ich auch einen Wert, wenn ich auf den "Uhrvater" -> in dem Fall "Autos" klicke. Komisch, aber naja...
Ich dachte, es gibt evtl. eine günstigere Lösung, aber so kann ich auch damit arbeiten. Der Geschwindigkeitsgewinn war schon enorm!!!
Vielen Dank
Cyberax
|
|
|