Autor Beitrag
Barret
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 156
Erhaltene Danke: 1

Win XP
D7 Ent
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 285
Erhaltene Danke: 33


DX10 Berlin Professional
BeitragVerfasst: Fr 26.11.10 21:06 
Hallo...

in der DP ist das Thema schon mal behandelt worden.
www.delphipraxis.net...eeview-von-jedi.html
oder hier...
www.delphipraxis.net...-mit-dbtreeview.html
Barret Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 156
Erhaltene Danke: 1

Win XP
D7 Ent
BeitragVerfasst: 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):
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 156
Erhaltene Danke: 1

Win XP
D7 Ent
BeitragVerfasst: 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

ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 156
Erhaltene Danke: 1

Win XP
D7 Ent
BeitragVerfasst: 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
ausblenden volle Höhe SQL-Anweisung
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 156
Erhaltene Danke: 1

Win XP
D7 Ent
BeitragVerfasst: 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:
ausblenden 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 //Datensätze zu Array fügen
        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//Ende while

        //Abbruch wenn keine Datensatz zum Array gefügt wird & das Ende des Array erreicht ist
        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//Ende while

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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 156
Erhaltene Danke: 1

Win XP
D7 Ent
BeitragVerfasst: Do 09.12.10 23:10 
*JUBEL JUBEL FREU FREU*

Endlich is es fertig!

ausblenden volle Höhe 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:
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
    //Maximale Elemente das Baums finden
    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;
    //*****

    //Startpunkt des Baumes finden
    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 //sortiertes nicht mehr beachten
      begin
        if i > 0 then SQL.Add(', ');
        SQL.Add(IntToStr(arr_ausgabe[i]));
      end;

      SQL.Add(') ORDER BY reihenfolge');
      Open; First;

      //Sortierung abspeichern & Baum-Pfadbestimmen in dem gesucht wird
      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.