Problem beim Löschen aus MySQL und Importieren

Hallo,

ich habe versucht einen PHP-Script zu bauen, der mir soviele Datensätze aus meiner MySQL-Tabelle exportiert und anschließend löscht, damit nur noch die 100 neusten übrig bleiben. Des Weiteren soll ein zweiter Script die Datensätze in eine andere Relation einfügen, die als Archiv dient.

Allerdings hat der erste Script jetzt schon mehrmals meine Relation zerfetzt, der zweite Script importiert falsch* und ich finde einfach keine Lösung.

Hier anbei die 2 Scripts, die ich zum Exportieren / Löschen und Importieren verwende.

Herausfinden, Exportieren und Löschen:

[code]$rows = mysql_result(mysql_query("SELECT count() FROM «relation»"),0); // Datensätze zählen
/
echo $rows.’ Einträge
’; */

for ($rows = $x; $x <= 100; $x–) { // Wenn es mehr als 100 Datensätze sind, dann…
$query1 = ‘SELECT * FROM «relation» ORDER BY Msg_ID ASC’;
$sql = mysql_query($query1) or die(mysql_error());
$oldest = mysql_result($sql,0); // den ältesten Eintrag suchen…
/* echo ‘Älteste ID: ‘.$oldest.’
’; */

$stmt = mysql_query("SELECT * FROM «relation» WHERE Msg_ID ='$oldest'");
$row = mysql_fetch_assoc($stmt);
$export = ',

(’.$row[“Msg_ID”].’, ‘’.$row[“Sender”].’’, ‘’.str_replace("’", “’”, $row[“Message”]).’’, ‘’.$row[“Timestamp”].’’)’; // seine Daten auslesen…
/* echo $export.’
’; */

$rowfile = fopen(“messages.dat”,“a”);
fwrite($rowfile,$export); // in eine Datei speichern…
fclose($rowfile);

$query2 = ‘DELETE FROM «datenbank».«relation» WHERE «relation».Msg_ID = ‘.$oldest.’ LIMIT 1’; // und aus der Datenbank löschen…
mysql_query($query2);
} // …bis es wieder 100 Datensätze sind.[/code]

In andere Relation importieren:

[code]include(“includes/database/connect.db.php”);

$import = “INSERT INTO «relation» (Msg_ID, Sender, Message, Timestamp) VALUES”;
$rowfile = file_get_contents(“messages.dat”);
$import .= substr($rowfile, 1);
$import .= “;”;
mysql_query($import);[/code]* Falscher Import in Punkto Umlauten. Wenn ich den Script wie oben laufen lassen, denn werden zwar die Umlaute richtig in die Datenbank eingefügt, aber der Output-Script kann es nicht mehr lesen. Wenn ich statt “file_get_contents(“messages.dat”);” den Inhalt der messages.dat einsetze, dann werden die Umlaute ‘falsch’ in die Datenbank eingefügt, aber der Output-Script kann es lesen. Warum?!

Schon einmal vielen Dank im Vorraus beim Helfen.
Falls Syntax-Highlighting benötigt ist, kann ich es auch via. Pastebin einbinden.

Gruß, DMan

mysql_query(“SET NAMES ‘utf8’”);

Deine Tabelle «relation» zu nennen ist vielleicht etwas ungünstig. Es mag funktionieren, aber wirklich ratsam ist es nicht. Der Name sollte schon vollständig ASCII sein.

Du liest $rows aus, und hier in der for-schleife setzt du $rows auf einen anderen Wert (was immer $x gerade ist).
Den Rest hab ich mir nicht so im detail angeschaut.

Du kannst dein Problem wahrscheinlich mit einem einzigen Query lösen (wie so häufig).
Mit subquery evt. etwas in der art:

oder so ähnlich…

[quote=“Balmung”]Deine Tabelle «relation» zu nennen ist vielleicht etwas ungünstig. Es mag funktionieren, aber wirklich ratsam ist es nicht. Der Name sollte schon vollständig ASCII sein.[/quote]Ich hab nur hier das so genannt.

[quote=“Balmung”]

Du liest $rows aus, und hier in der for-schleife setzt du $rows auf einen anderen Wert (was immer $x gerade ist).
Den Rest hab ich mir nicht so im detail angeschaut.[/quote]
$rows ≙ Anzahl der Datensätze.
Und jetzt wird $rows gleich dem klassischen $x gesetzt.

Solange, bis X (die Anzahl der Datensätze) kleiner gleich 100 ist, soll diese for-Schleife durchgeführt werde.

Achso.

Zu meinem Query: Der sub-query liest die 100 neuesten ids aus, und mit dem äußeren DELETE query, lösche ich alle datensätze die NICHT in dem sub-query enthalten sind. Eigentlich ganz easy :slight_smile:

Wollte das noch nachfragen. ^^

PS: Hab noch was hinzugefügt, dachte nicht, dass so schnell ne Antwort kommt. :o
Vielen Dank. (:

[quote=“DManstrator”]Und jetzt wird $rows gleich dem klassischen $x gesetzt.

Solange, bis X (die Anzahl der Datensätze) kleiner gleich 100 ist, soll diese for-Schleife durchgeführt werde.[/quote]
Mit dem Problem, dass du nicht $x setzt, sondern $rows (du überschreibst $rows mit dem Wert aus $x… und $x ist womöglich leer(?) - wer weiß schon was genau PHP in dem Fall macht :smiley:).

Was du wahrscheinlich meintest ist: $x = $rows

Das könnte es sein.

Hatte davor “x = $rows” dastehen und das gab nen Error aus. Hab das also einfach umgedreht. Und nachdem ich bemerkt habe, dass das hier mehr Mathe als PHP war, hab ich das Dollar-Zeichen hinzugefügt, aber sonst alles gelassen. Ich probier es heute Nachmittag nochmal aus, wenn es nicht klappt, dann nehm ich deins. :smiley:

Kannst du zu meinem anderen Problem nochwas genaueres sagen, netsplit hat es etwas ungenau formuliert…

Vielen Dank schonmal! (:

Schwer zu sagen was da nicht stimmt.

Es gibt eine Reihe Orte, an denen man überprüfen muss, ob alles in der korrekten Kodierung eingestellt ist:

Nehmen wir mal an du willst alles zur Zeichenkodierung UTF-8 stellen.

[ul]
[li] Der Texteditor zum Editieren von PHP scripten sollte auf UTF-8 gestellt werden. Falls der Editor eine Option für “BOM” aka “Byte Order Mark”, dann auf jeden falls “ohne BOM”.[/li]
[li] Die Datenbank und Tabelle sollten alle auf utf-8/unicode gestellt sein.[/li]
[li] Die Datenbankverbindung (das SET NAMES) sollte ebenfalls auf utf8 gestellt sein.[/li]
[li] Die Ausgabe zum Browser sollte per PHP script, mit dem header() Befehl, ebenfalls auf einen utf-8 content-type gestellt sein. Möglicherweise kann man das auch mit .htaccess machen.[/li]
[li] Schließlich müssen die Daten, die du aus den Dateien liest, ebenfalls utf-8 kodiert sein, oder beim einlesen nach utf-8 kodiert werden, wenn die Zeichenkodierung der Dateien nicht utf-8 ist. Dazu musst du herausfinden welche Zeichenkodierung die Daten in der Datei haben.[/li][/ul]

Als Zusatzpunkt sollte man sich selbst noch einmal klar machen, was Unicode (und Zeichenkodierungen wie utf-8) überhaupt ist: joelonsoftware.com/articles/Unicode.html

Edit: und auch relevant, weil mysql doof ist, gibt es (mindestens) zwei utf8 Zeichenkodierungen: utf8 und utf8mb4.

mfg Balmung

Evtl. sollte ich das einfach mal vom Windows-PC speichern, da kann man ja schon schöne die Kodierungs auswählen. x)

Andere Frage, bei der for-Schleife. Hab ja “$x <= 100”. Heißt es dann, dass die Schleife bis dahin oder ab dahin funktioniert? Weil momentan passiert nichts, obwohl $cols ($x) > 100 ist.

Übernimmst du die Änderung wie folgt:

bedeutet das:

[ul][li] Setze $x beim Einstieg auf den Wert aus $rows.[/li]
[li] Wiederhole den Schleifenrumpf (den Inhalt zwischen { und }) so lange der Wert aus $x kleiner oder gleich 100 ist.[/li]
[li] Verringere $x mit jeden Durchlauf um 1.[/li][/ul]

Klingt nicht besonders richtig :slight_smile:

In dem Fall, dass $x bereits beim Einsteig kleiner oder gleich 100 ist, würde der $x immer weiter verringern und irgendwann an 0 vorbei ins negative gehen… Und weil PHP integers, afaik, 32 bit signed integers sind, würde der dann noch ungefähr 2 milliarden weitere schleifendurchläufe, durch alle möglichen Negativen Werte (die ja alle kleiner als 100 sind) machen, bis er durch den Underflow wieder am anderen positiven Ende des Integers landet und dann (endlich) abbricht.

mfg Balmung

Jo, war falsch. Hab das Zeichen umgedreht und jetzt geht’s. (:

Selbst das mit der Kodierung klappt jetzt aus irgendeinem Grund. :DD

Vielen Dank für deine Hilfe. (:

PS: Hab’s jetzt automagisiert. JS aktualisiert den Script immer jede Sekunden und so wird immer, wenn es mehr als 100 Nachrichten sind, die älteste in ne andere Datei exportiert, gelöscht, importiert und abschließend wird die Datei gelöscht. Auch Quotes wie " und ’ werden davor escaped, damits nicht zu Problemen kommt. ^^

Den Teil kann ich ja hier mal posten:

$quotes = array("'", '"'); $betterquotes = array("\'", '\"'); $export = ', ('.$row["Msg_ID"].', \''.$row["Sender"].'\', \''.str_replace($quotes, $betterquotes, $row["Message"]).'\', \''.$row["Timestamp"].'\')';

“jede Sekunde”…

Ist das nicht ein bisschen unsinnig? Davon mal abgesehen, dass EIN query, wie ich ihn gezeigt hab, wesentlich performanter ist, ist es doch noch viel besser, überflüssige Einträge nur dann zu entfernen, wenn du einen Neuen Eintrag einfügst. Es ist ja nicht so, dass die Datensätze auf magische Weise einfach anwachsen.

[quote=“Balmung”]dass EIN query, wie ich ihn gezeigt hab, wesentlich performanter ist[/quote]Klar ist das performanter aber ich bau lieber auf das, was ich mir zusammenstecke. Ich bin erst auf diesem Level und muss noch mehr lernen, um auf dein Level zu kommen. War auch eig. meine erste for-Schleife und du hast gesehen, was da für Nonsense rauskam.
Kurz und knapp: Viel zu lernen ich noch hab.

[quote=“Balmung”]überflüssige Einträge nur dann zu entfernen, wenn du einen Neuen Eintrag einfügst.[/quote]Könnte den Script natürlich auch dann ausführen lassen, wenn eine Nachricht abgeschickt wird, hab aber zuerst daran gedacht, ihn an den Auto-Effekt mitanzuhängen.

Nochmal danke für alles. (:

[size=85]psssst vllt willst du dir es noch mal anders überlegen… die sache mit PHP meine ich :p
http://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/[/size]

Im Ernst: hast du schon ein paar Tutorials gelesen?
Folgendes gehört angeblich zu einem der besseren: tut.php-quake.net/