Sortiereihenfolge ändern -> Optimierung
Bobby
- datenbank
Moin
Ich hab eine Tabelle mit Werten, die ID, Name und Orderzahl beinhaltet. ID und Orderzahl sind unique.
Ich möchte nun einzelnen Punkte nach oben und unten verschieben.
ungefähr so (h steht für Link nach oben und r für Link eine Position nach unten):
h r Name1
h r Name2
h r Name3
h r Name4
Wenn ich jetzt den Link 1 Position hoch betätige z.B. beim Wert Name3 soll das Ergebnis dann folgendermaßen aussehen:
h r Name1
h r Name3
h r Name2
h r Name4
In der Tabelle wurden die Werte der Orderzahl getauscht. Im Moment geschiehht dies durch mehrere Querys. Können diese irgendwie auf ein Query zusammen gefasst werden?
// zu tauschendes Element holen
$menufac->getPointById($_GET['id']);
$menu=$menufac->getElement();
// Nebenstehendes Element holen
$menufac->getPointSelfNested($menu->ordering,$_GET['mode']);
// Wenn nebenstehendes Element vorhanden ist
if($menu2=$menufac->getElement())
{
// OrderID des nebenstehenden Elementes auf 99999999999 setzen
$menufac->update("orderzahl='99999999999'","id",$menu2->id);
// OrderID des zu verschiebenden Elementes mit dem des nebenstehenden Elementes tauschen
$menufac->update("orderzahl='".$menu2->orderzahl."'","id",$menu->id);
// OrderID des nebenstehenden Elementes mit dem zu verschiebenden Elementes tauschen
$menufac->update("orderzahl='".$menu->orderzahl."'","id",$menu2->id);
}
Da ich viel über Objekte gehe, hoffe ich das ihr damit was anfangen könnt. Also, jedes "$menufac->update" erzeugt einen neuen Query.
Das Beispiel führt folgende Querys nacheinander aus (mit dem Beispiel von oben)
SELECT * FROM menu a WHERE id='3'
SELECT * FROM menu b WHERE orderzahl <'3' ORDER BY orderzahl DESC LIMIT 0,1
UPDATE menu SET orderzahl='99999999999' WHERE id=b.id
UPDATE menu SET orderzahl=b.orderzahl WHERE id=a.id
UPDATE menu SET orderzahl=a.orderzahl WHERE id=b.id
Ich setze zuerst die Orderzahl des nebenstehenden Elementes auf einen extrem hohen Wert und tausche dann die beiden Orderwerte des jeweiligen Datensatzes. Ich muss so vorgehen, da die Spalte orderzahl ja unique ist.
Das Element mit der ID 3 hat nun den Wert 2 als Orderzahl und das Elmenent ID 2 hat den Wert 3 als Orderzahl.
Also, wie kann ich dies optimieren.
Gruß Bobby
Moin
Ich vergas. Es handelt sich natürlich um eine MySQL-Datenbank.
Gruß Bobby
Hallo,
Ich hab eine Tabelle mit Werten, die ID, Name und Orderzahl beinhaltet. ID und Orderzahl sind unique.
Ich möchte nun einzelnen Punkte nach oben und unten verschieben.
Also, wie kann ich dies optimieren.
CALL proc_swap_order(17, 4)
vertauscht die Sortierpositionen der Datensätze mit den ID-Werten 17 und 4.
Wäre dies genehm?
Voraussetzung: MySQL 5.x oder neuer.
Umsetzung: mit Stored Procedure.
Als Anwender bevorzugte ich jedoch eine Lösung, bei der ich nicht nur immer um eine Position ändern könnte. Ich möchte die neue Sortierung insgesamt vornehmen und anschließend speichern. Dafür böte es sich an, den Sortierschlüssel komplett neu zu schreiben. Ein Problem hast Du allerdings bei Blättermechanismen.
Freundliche Grüße
Vinzenz
Moin
Umsetzung: mit Stored Procedure.
Und da haperts.
CREATE PROCEDURE datenbank.position_up (IN param1 INT)
BEGIN
SELECT * FROM menu a WHERE id=param1;
SELECT * FROM menu b WHERE b.orderzahl<a.orderzahl ORDER BY orderzahl DESC LIMIT 0,1;
UPDATE menu SET orderzahl='99999999999' WHERE id=b.id;
UPDATE menu SET orderzahl=b.orderzahl WHERE id=a.id;
UPDATE menu SET orderzahl=a.orderzahl WHERE id=b.id;
END
Dies wird mir mit folgendem Fehlercode quittiert: #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 3
Wo liegt mein Denkfehler? Hab das noch nie gemacht und benötige Hilfe.
Gruß Bobby
Hallo Bobby,
Umsetzung: mit Stored Procedure.
Und da haperts.
CREATE PROCEDURE datenbank.position_up (IN param1 INT)
Wieviele Parameter hat mein Aufruf? Richtig: 2.
BEGIN
-- zwei völlig überflüssige SELECT-Anweisungen, weg damit. Du weißt doch, welche Datensätze Du vertauschen willst. Ja, Deine Applikation muss Dir genau die zwei ID-Werte liefern. Wenn sie's für einen Datensatz kann, dann auch für zwei.
SELECT * FROM menu a WHERE id=param1;
SELECT * FROM menu b WHERE b.orderzahl<a.orderzahl ORDER BY orderzahl DESC LIMIT 0,1;
SPs sind atomar. Du kannst ohne Probleme den maximalen Wert Deiner orderzahl-Spalte plus 1 statt eines hartcodierten Wertes nehmen und für die WHERE-Klausel nimmst Du die ID-Werte aus der Übergabe.
UPDATE menu SET orderzahl='99999999999' WHERE id=b.id;
UPDATE menu SET orderzahl=b.orderzahl WHERE id=a.id;
UPDATE menu SET orderzahl=a.orderzahl WHERE id=b.id;
END
> Dies wird mir mit folgendem Fehlercode quittiert: #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 3
MySQL hat SPs erst spät eingebaut und möchte daher für seine "normalen" Anweisungen während der Abarbeitung des CREATE-Statements ein anderes Trennzeichen (Delimiter) für SQL-Anweisungen haben. Nimm den doppelten Slash.
Nimm dafür einen netten Client wie phpMyAdmin, der bietet Dir eine Eingabmöglichkeit für einen anderen Delimiter unterhalb der SQL-Textarea an.
Freundliche Grüße
Vinzenz
Moin
Erstmal danke. Ich werds morgen ausprobieren.
MySQL hat SPs erst spät eingebaut und möchte daher für seine "normalen" Anweisungen während der Abarbeitung des CREATE-Statements ein anderes Trennzeichen (Delimiter) für SQL-Anweisungen haben. Nimm den doppelten Slash.
Das hatte ich bei erneuter Recherche bereits rausgefunden. Aber danke für den Hinweis.
Gruß Bobby
Moin
Erstmal danke. Ich werds morgen ausprobieren.
Also ich habs nicht hinbekommen. Muss ich mich in Ruhe nochmal mit beschäftigen.
Fehlermeldung heist jetzt:
Es scheint einen Fehler in Ihrer MySQL-Abfrage zu geben. Die MySQL-Fehlerausgabe, falls vorhanden, kann Ihnen auch bei der Fehleranalyse helfen.
ERROR: Unbekannte Interpunktion @ 94
Ich hab mal spaßeshalber mitgezählt. Es ist der Begrenzer der nicht richtig genommen wird. Ich hab doppelte Slash verwendet. Client ist PhpMyAdmin. Was muss ich bei der Vergabe des delimiters noch beachten?
Gruß Bobby
Moin
ERROR: Unbekannte Interpunktion @ 94
Ich hab mal spaßeshalber mitgezählt. Es ist der Begrenzer der nicht richtig genommen wird. Ich hab doppelte Slash verwendet. Client ist PhpMyAdmin. Was muss ich bei der Vergabe des delimiters noch beachten?
OK, jetzt hab ich das mit dem Delimiter richtig verstanden. Die Querys werden angenommen. Leider scheinen mir die Rechte zu fehlen um eine Prozedur anlegen zu dürfen. Gibt es da auch noch einen Trick?
Fehlermeldung:
#1044 - Access denied for user 'username'@'localhost' to database 'datenbank'
Gruß Bobby
Hi,
Leider scheinen mir die Rechte zu fehlen um eine Prozedur anlegen zu dürfen. Gibt es da auch noch einen Trick?
Ja - er lautet: Rechte vergeben (lassen).
MfG ChrisB
Moin
Ja - er lautet: Rechte vergeben (lassen).
Leider nicht möglich. Aber trotzdem danke.
Gruß Bobby