Autor |
Beitrag |
Barret
      
Beiträge: 156
Erhaltene Danke: 1
Win XP
D7 Ent
|
Verfasst: Fr 26.11.10 19:49
Hallo!
Ich hab grad ein kleines Problem bei einem einfachen Sortieforgang....
Ich hab eine Tabelle in der ich daten für ein TJvDBTreeView sortieren will.
Das Ergebnis soll sein, dass ich einen Tree komplett bis nach unten laufen und dann erst in den nächsten springe.
Beispiel:
a
-b
--e
--f
---g
-c
Hierbei soll er so laufen wenn ich im Navigator weiter drücke: a -> b -> e -> f -> g -> c
Ich habe für die Komponente ein id-Feld und ein sub_is-Feld auf welches das id referenziert.
Er soll die Bäume auch vernünftig durchlaufen wenn neue Datensätze eingetragen werden.
Ich habe schon überlegt ein Zusatzfeld Position anzulegen aber da bin ich noch zu keinen 100% Ergebniss gekommen.
Auf jedenfall will ich z.b. auch zwischen e & f ein Feld einfügen können ohne das ich gr. Positionsangaben auf der Vertikalen Ebene machen muss.
Jemand da spontan eine Idee für die DB-Struktur und deren sortierung?
_________________ Wir könnten ja, wenn wir wollten aber wir wollen ja nicht.
It´s not a bug, it´s a feature.
|
|
haentschman
      
Beiträge: 285
Erhaltene Danke: 33
DX10 Berlin Professional
|
Verfasst: Fr 26.11.10 21:06
|
|
Barret 
      
Beiträge: 156
Erhaltene Danke: 1
Win XP
D7 Ent
|
Verfasst: Do 02.12.10 17:44
Ich hab gedacht, dass ich es hätte. Wird aber in den beiden hemen auch nicht richtig beschrieben was ich vorhabe.
Jetzt bin ich eig soweit mi durch mit dem Modul und im ersten Praxistest zeigt sich dann, dass meine Sortierung doch nich hinhaut.
Ich habe immer einen Rootknoten, von daaus komme ich beim durchkliken mit dem DB-Navigator auch noch so halb "richtig" durch die 1. Ebende durch ...
Im Moment is es bei mir so wenn ich mit dem Navigator "Next" mache:
a
-b
--e
--f
---g
-c
-- h
a->b->c->h->e->f In Abhängigkeit wann ich welches Objekt erstellt habe.
Hier mal der SQL-String (nur zur Verständlichkeit etwas umbenannt):
SQL-Anweisung 1:
| SELECT * FROM tbl_eins ORDER BY sub_id, position, name ASC |
Als Felder in der Tabelle hab ich: id - Primärschlüssel & auti-inc. als Parent, sub_id als Child-Feld, position um die Reihenfolge der jeweiligen Child-Elemente richtig zu sortieren und name um ein String-Element aufzunehmen.
Ich möchte nun aber schaffen, dass er a->b->e->f->g->c->h durchgeht beim "Next". Mir fällt aber grad nichts ein für die richtige Sortierung in der Query. Durch die Eigenschaften der JcDBTreeView passt die reine Darstellung der Daten aber in Form wie ich Sie auch haben möchte.
_________________ Wir könnten ja, wenn wir wollten aber wir wollen ja nicht.
It´s not a bug, it´s a feature.
|
|
Barret 
      
Beiträge: 156
Erhaltene Danke: 1
Win XP
D7 Ent
|
Verfasst: Di 07.12.10 19:00
Nabend!
Ich hab etwas suchen müssen aber jetzt hab ich was gefunden, was hin kommen sollte.
forum.fachinformatik...tur-sql-abfrage.html
SQL-Anweisung 1: 2: 3: 4: 5: 6:
| SELECT id, name, url, icon, target, vaterordner FROM ordner WHERE role IN (SELECT granted_role FROM user_role_privs) START WITH id = 1 CONNECT BY vaterordner = PRIOR id ORDER SIBLINGS BY name |
Nach langem lesen bin ich noch nich richtig weiter. Ich muss jetzt noch versuchen den Teil aus der Oracel DB auf meine MySQL zu portieren. Also von der Abfrage her. Leider gibt es die Funktion CONNECT BY nicht. Jemacht schon sowas gemacht? Ne gute lösung für was vergleichbares find i grad nich...
_________________ Wir könnten ja, wenn wir wollten aber wir wollen ja nicht.
It´s not a bug, it´s a feature.
|
|
Barret 
      
Beiträge: 156
Erhaltene Danke: 1
Win XP
D7 Ent
|
Verfasst: Mi 08.12.10 10:54
So weiter gehts.
Ich bin fündig geworden was ne mysql fFunktion angeht.
www.delphipraxis.net/740213-post1.html
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: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54:
| CREATE DEFINER=`root`@`localhost` PROCEDURE `proc_GetNodes`(NodeID INTEGER) BEGIN DECLARE _Depth INT DEFAULT 1; DECLARE _Done INT DEFAULT 0;
CREATE TEMPORARY TABLE tmpTable ( id INT PRIMARY KEY, Depth INT, NodePath VARCHAR(1000) ) TYPE=HEAP; CREATE TEMPORARY TABLE tmpTable2 ( id INT PRIMARY KEY, Depth INT, NodePath VARCHAR(1000) ) TYPE=HEAP;
IF NodeID IS NULL THEN INSERT tmpTable (id, Depth, NodePath) SELECT id, _Depth, id FROM nodes WHERE parentid IS NULL; ELSE INSERT tmpTable (id, Depth, NodePath) SELECT id, _Depth, id FROM nodes WHERE parentid = NodeID; END IF; IF ROW_COUNT() = 0 THEN SET _Done = 1; END IF; WHILE _Done = 0 DO SET _Depth = _Depth + 1; INSERT tmpTable2 (id, Depth, NodePath) SELECT t.id, _Depth, CONCAT(x.NodePath, '|', id) FROM nodes t INNER JOIN tmpTable x ON t.parentid = x.id WHERE x.Depth = _Depth-1; IF ROW_COUNT() = 0 THEN SET _Done = 1; END IF; INSERT tmpTable SELECT * FROM tmpTable2; DELETE FROM tmpTable2; END WHILE;
SELECT t.id, t.bez, x.Depth, x.NodePath FROM nodes t INNER JOIN tmpTable x ON t.id = x.id ORDER BY x.NodePath;
DROP TEMPORARY TABLE tmpTable; DROP TEMPORARY TABLE tmpTable2; END; |
Wenn ich das jetzt aufrufe sagt er mir, dass das feld id nicht eindeutig zuzuordnen ist.
Ich steig da noch nich ganz durch aber evtl einer der etwas mehr ahnung von euch hat?!
_________________ Wir könnten ja, wenn wir wollten aber wir wollen ja nicht.
It´s not a bug, it´s a feature.
|
|
Barret 
      
Beiträge: 156
Erhaltene Danke: 1
Win XP
D7 Ent
|
Verfasst: Do 09.12.10 18:32
So...
ich hab mir jetzt was anderes überlegt.
Ich muss das ganze nicht in der Query schon sorteirt haben. Ich kann das auch über nen Array machen. Dann müssen die Daten nur dort richtig sortiert werden.
Für das löschen eines ganzes Astes hab ich mir dies hier zusammengebaut:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| while not b_loeschen_fertig do begin First;
while not Eof do begin if FieldByName('sub_id_app_menue_xml_inhalte_content').AsInteger = arr_Baum_Loeschen[i] then begin SetLength(arr_Baum_Loeschen, Length(arr_Baum_Loeschen) + 1); arr_Baum_Loeschen[Length(arr_Baum_Loeschen) - 1] := FieldByName('id_app_menue_xml_inhalte_content').AsInteger; b_eintrag_gefunden := true; end;
Next; end; if b_eintrag_gefunden = true then b_eintrag_gefunden := false else if i = Length(arr_Baum_Loeschen) - 1 then b_loeschen_fertig := true;
i := i + 1; end; |
Baut auf ner Query auf.
b_loeschen_fertig, b_eintrag_gefunden = boolean
arr_Baum_Loeschen = array of Integer
Im Anschluss lauf ich halt den Array durch und lösche alle Datensätze.
Jetzt will ich das quasy für den Export Teilweise nutzen.
Dazu muss ich ja nur die Wurzel haben (Kein Problem).
Deren Kinder finden und nach "reihenfolge" sortieren (auch kein Problem).
Wenn ich jetzt die Liste durchlaufe muss ich aber den Ast von dort aus weiter runterlaufen bis ich am Ende angekommen bin und das einen weiter Springen in der 1. Child-Liste. Stichwort dabei ist "Rekursion". Nur gut, dass ich genau davon keinen Plan hab wie ich das anstelle weil ja jedes Child Element der Wurzel n Childs haben kann.
Das Problem zu lösen ist bestimmt einfacher?!
_________________ Wir könnten ja, wenn wir wollten aber wir wollen ja nicht.
It´s not a bug, it´s a feature.
|
|
Barret 
      
Beiträge: 156
Erhaltene Danke: 1
Win XP
D7 Ent
|
Verfasst: Do 09.12.10 23:10
*JUBEL JUBEL FREU FREU*
Endlich is es fertig!
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: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77:
| procedure array_sortieren(i_uebergabe : Integer); var i_max, i_parent, i, i_ende : Integer; b_ende : Boolean; arr_test : array of Integer; arr_ausgabe : array of Integer; s_ausgabe : String; begin b_ende := false; i := 0; i_ende := 1; SetLength(arr_test, 1); SetLength(arr_ausgabe, 1);
with D_Datenmodul.qu_plz_ort do begin Close; SQL.Text := 'SELECT COUNT(id_app_menue_xml_inhalte_content) as maximum '; SQL.Add('FROM tbl_app_menue_xml_inhalte_content '); SQL.Add('WHERE tbl_app_menue_xml_inhalte_id = '''+IntToStr(i_uebergabe)+''''); Open; First; i_max := FieldByName('maximum').AsInteger; Close; SQL.Text := 'SELECT id_app_menue_xml_inhalte_content as parent_element '; SQL.Add('FROM tbl_app_menue_xml_inhalte_content '); SQL.Add('WHERE tbl_app_menue_xml_inhalte_id = '''+IntToStr(i_uebergabe)+''' + AND sub_id_app_menue_xml_inhalte_content = 0'); Open; First; arr_test[0] := FieldByName('parent_element').AsInteger; arr_ausgabe[0] := FieldByName('parent_element').AsInteger; while not b_ende do begin Close; SQL.Text := 'SELECT id_app_menue_xml_inhalte_content '; SQL.Add('FROM tbl_app_menue_xml_inhalte_content '); SQL.Add('WHERE sub_id_app_menue_xml_inhalte_content = '''+IntToStr(arr_test[Length(arr_test) - 1])+''' '); SQL.Add('AND id_app_menue_xml_inhalte_content not in (');
for I := 0 to Length(arr_ausgabe) - 1 do begin if i > 0 then SQL.Add(', '); SQL.Add(IntToStr(arr_ausgabe[i])); end;
SQL.Add(') ORDER BY reihenfolge'); Open; First;
if not Eof then begin SetLength(arr_ausgabe, Length(arr_ausgabe) + 1); arr_ausgabe[Length(arr_ausgabe) - 1] := FieldByName('id_app_menue_xml_inhalte_content').AsInteger; i_ende := i_ende + 1;
SetLength(arr_test, Length(arr_test) + 1); arr_test[Length(arr_test) - 1] := FieldByName('id_app_menue_xml_inhalte_content').AsInteger; end else SetLength(arr_test, Length(arr_test) - 1); if i_ende = i_max then b_ende := true; end; end;
for I := 0 to Length(arr_ausgabe) - 1 do s_ausgabe := s_ausgabe + ', ' + IntToStr(arr_ausgabe[i]);
if (MessageDlg(s_ausgabe, mtWarning, [mbYes, mbCancel], 0) = mrYes) then begin
end; end; |
Die Benennung is noch fürn hintern aber dafür wars ja auch nen Test in den Abendstunden.
Werd das die Tage mal vernünftig machen und online stellen.
Ausgehende Tabellenstruktur is ja oben.
_________________ Wir könnten ja, wenn wir wollten aber wir wollen ja nicht.
It´s not a bug, it´s a feature.
|
|
|