Phil: Menü-Reihenfolge ändern

In einem CMS soll eine Navileiste erscheinen.

DB:

ID ORDER  Name  usw.
---------------------------------------------
1 1  Home  ...
2 2  News  ...
3 3  Links  ...
4 4  Impressum ...
5 5  Mail  ...

Ich möchte jetzt per Befehl die Reihenfolge ändern.
In der Adminoberfläche könnten z.B. neben jedem
Link Zwei Bottons "Aufwärts" / "Abwärts" stehen.

Soll die Zeile 3 also zu 2 Zeile werden, müssten in der
DB-Spalte "Order" Zeile "3" -1 ; in der Vorherigen +1
eingetragen werden.

Wie könnte man hier die MySql- Abfrage und PHP
Script gestalten?

Vilen Dank,

Phil

  1. Hi Phil,

    Wie könnte man hier die MySql- Abfrage und PHP Script gestalten?

    Zu diesem Problem dürftest du auch im Archiv ein paar Antworten finden. Unter anderem auch diesen Lösungsansatz von mir, welcher schon etwas älter ist. Ob neuere MySQL-Versionen da komfortablere Möglichkeiten bieten weiß ich nicht, glaube ich aber nicht.

    Viele Grüße,
      ~ Dennis.

    1. Hello Dennis,

      Zu diesem Problem dürftest du auch im Archiv ein paar Antworten finden. Unter anderem auch diesen Lösungsansatz von mir, welcher schon etwas älter ist. Ob neuere MySQL-Versionen da komfortablere Möglichkeiten bieten weiß ich nicht, glaube ich aber nicht.

      Habe das eben nur kurz überflogen, aber so handelst Du Dir ein mächtiges Nebenläufigkeitsproblem ein.
      http://de.wikipedia.org/wiki/Nebenläufigkeit

      Du musst die Tabelle entweder sperren, während die einzelnen Statements zur selben Sache ausgeführt werden, oder aber einen anderen Weg gehen.

      Auch das Ermitteln der IDs in separaten Statements unterliegt noch einer Race-Condition
      Das muss also mit gekapselt werden.

      Harzliche Grüße aus
      Sankt Andreasberg
      und Guten Rutsch

      Tom

      --
      Nur selber lernen macht schlau

  2. Hello,

    da bnötigst Du eine atomar gebundene Bubblefunkiton... :-)

    set @id = 4;
    set @b_id = @id;

    #nach oben rücken
        select a.id_zeit, lfd_nr into @a_id, @a_nr FROM zeit AS a where a.lfd_nr < (select @b_nr:= b.lfd_nr from zeit as b where b.id_zeit = @id) order by a.lfd_nr desc limit 1;
        select @a_id, @a_nr, @b_nr;

    #nach unten rücken
        select a.id_zeit, lfd_nr into @a_id, @a_nr FROM zeit AS a where a.lfd_nr > (select @b_nr:= b.lfd_nr from zeit as b where b.id_zeit = @id) order by a.lfd_nr asc limit 1;
        select @a_id, @a_nr, @b_id, @b_nr;

    Ich ahbe es nun nicht extra auf Deine Verhältnisse umgeschrieben, das musst Du bitte mal selber machen.

    lfd_nr ist hier das Feld, das für die Sortierung verantwortlich ist.

    Zugegriffen wird nicht über die laufende Nummer, sondern über die ID des Datensatzes, den man verschieben will. Diese Anfprderung sit aus der Praxis entstanden.

    Du musst die beiden Benutzervariablen setzen und dann kannst Du das jeweilige Statement aufrufen.
    Wesentliche Überlegung ist dabei, dass die Datenmanipulation in EINEM EINZIGEN Statement stattfinden muss, wenn Du die tabelle nicht sperren willst. Anderenfalls riskierst Du die Integrität der Daten.

    Die Uservariablen sind verbindungs-autark, das bedeutet, dass Du Dir da keine Race-Condition einhandelst, wenn die in zwei Statements vorab gesetzt werden.

    Wahrscheinlich kann man es auch noch optimieren, aber ich habe jetzt keine Lust dazu :-)

    Mein MySQL ist down

    Harzliche Grüße aus
    Sankt Andreasberg
    und Guten Rutsch

    Tom

    --
    Nur selber lernen macht schlau

    1. Hello,

      Hello,

      da bnötigst Du eine atomar gebundene Bubblefunkiton... :-)

      set @id = 4;
      set @b_id = @id;

      #nach oben rücken
          select a.id_zeit, lfd_nr into @a_id, @a_nr FROM zeit AS a where a.lfd_nr < (select @b_nr:= b.lfd_nr from zeit as b where b.id_zeit = @id) order by a.lfd_nr desc limit 1;

      nur zur Kontrolle      select @a_id, @a_nr, @b_nr;

      #nach unten rücken
          select a.id_zeit, lfd_nr into @a_id, @a_nr FROM zeit AS a where a.lfd_nr > (select @b_nr:= b.lfd_nr from zeit as b where b.id_zeit = @id) order by a.lfd_nr asc limit 1;

      nur zur Kontrolle      select @a_id, @a_nr, @b_id, @b_nr;

      Zum bessere Verständnis. Die jeweils zweiten Statements waren nur für mich zur Kotrolle. Ich hatte vergessen, sie zu löschen für das Posting.

      Harzliche Grüße aus
      Sankt Andreasberg
      und Guten Rutsch

      Tom

      --
      Nur selber lernen macht schlau

  3. Danke soweit,

    das hilft weiter und enthält alle Antworten auf meine
    vergessenen Fragen. Ich werde das gleich mal durcharbeiten.

    Gruß
    Phil