SQL PHP/mySQL: warum zufälliges Löschen?

WulfmanGER

Commander
Registriert
Juli 2005
Beiträge
2.269
Hallo zusammen,

ich hab ein blödes Problem :( ich komme da einfach nicht weiter.

Ich nutze Calibre für die eBook-Verwaltung. Ich möchte aber die SQLlite-DB nach mySQL bewegen (paar Daten ... für schnelleres suchen etc. kein Ersatz für den Calibre-Webserver etc.!).

Dafür hab ich ein Import-Script geschrieben. Das klappt auch soweit. Natürlich kommt es mal vor das ich in Calibre Bücher, Autoren, Tags usw. lösche. Diese müssen dann natürlich in mySQL auch gelöscht werden. Da ich leider nicht mit SQLlite und mySQL parallel (also abgleich sql-lite vs. mysql) agieren kann. Lese ich eine Tabelle aus der SQLlite, schreibe diese in einer Temporären mySQL (MEMORY) und gleiche diese Tabelle mit der "Ziel"-Tabelle ab. Differenzen lösche ich in der Ziel-Tabelle.

Seit paar Tagen (das Script lief eigentlich sauber durch - ich hab nichts geändert). Passiert es alle 2-3 Updates das mir die halbe DB gelöscht wird ... Ich hab versuch den ersten "Lösch"-Block nachzuvollziehen. Laut meinem Test dürfte nichts gelöscht werden => ich starte script -> Tabelle wird gelöscht ...

Ich fülle also die temp-db

Code:
$db_sqlite = new SQLite3("h:/Calibre-DB/metadata.db");

$mysqli->query('TRUNCATE temp_delete_books'); 
$books_like = $db_sqlite->query("select * from books");

// Buch-IDs in Temp-Tabelle schreiben
while ($dsatz = $books_like->fetchArray(SQLITE3_ASSOC))
{
    $id = $dsatz['id'];
    $sql = "INSERT INTO temp_delete_books (id) VALUES ('$id')";
    $mysqli->query($sql);
}
Truncate (ist mysql!) der temp_delete_books um sicher zu gehen das diese auch leere ist bevor ich was reinschreibe.
Dann lese ich die Tabelle books in der SQLlite aus. Ich fülle die temp_delete_books.

Ich breche das Script dann hier ab und schaue was passiert:

Wie zu erwarten ist der KOMPLETTE Buchbestand (nur die IDs) in der temp_delete_books. SAUBER

Ich führe in der mySQL jetzt folgende Abfrage händisch durch:

Code:
SELECT b.id, b.title FROM books b LEFT JOIN temp_delete_books tdb ON b.id=tdb.id WHERE tdb.id is null
=> Ergebnis: es wird mir NICHTS angezeigt. Das ist richtig. Ich möchte ja wissen welche Bücher in der Calibre-DB gelöscht sind (in temp_delete_books steht der ganze aktuelle Buchbestand). Ich hab nichts gelöscht -> Ergebnis 0 ist richtig.

Wenn ich jetzt das Script weiterlaufen lasse, erwarte ich das nichts gelöscht wird.

Hier der Rest vom Script:

Code:
// Zu Löschenden IDs ermitteln und dann in ALLEN Tabellen löschen.
// wenn Buch Nr. 10 gelöscht ist sind natürlich mehre Tabellen betroffen. Bücher, Tags und Authorenverknüpfungen etc.)
$sql = "SELECT b.id, b.title FROM books b LEFT JOIN temp_delete_books tdb ON b.id=tdb.id WHERE tdb.id is null";
$result = $mysqli->query($sql);
// -> die Abfrage hab ich ja händisch durchgeführt => Ergebnis 0
$delCount = 0;
        while( $row = mysqli_fetch_assoc($result) ){
            $delCount += 1;
            $book_id = $row['id'];
            $book_title = $row['title'];
            $del = "DELETE FROM books WHERE id = '$book_id'";
            $mysqli->query($del);
			echo "Buch: <b>{$book_title} [{$book_id}]</b> gelöscht<br />";
// die while-Schleife dürfte gar nicht laufen, weil $result LEER ist. 
// Oder hab ich hier einen Denkfehler? Egal ... selbst wenn die läuft: 
// in $book_id ist logischerweise KEINE ID - woher auch.
[...]
Das Script geht natürlich noch weiter - es müssen noch andere Einträge gelöscht werden. Aber in dem teil sind schon ca. 90% aller Buch-IDs gelöscht. Ich hab auch keine Ahnung warum a) überhaupt und b) warum nicht ALLES gelöscht wird. Das ganze macht irgendwie keinen sinn :(

Zwischen händischen SELECT in der mySQL auf temp_delete_books und dem ablaufen des Scriptes passiert NICHTS weiter. Ich kann das händisch auch x-mal wiederholen ... Ergebnis Null. Script: großteil wird gelöscht.

Ich hab schon die Komplette DB geleert. Script aufgerufen. Tabelle wird gefüllt - das "aufräumscript" läuft direkt danach - leert die Tabelle gleich wieder.

Troubleshooting-Ideen?

Edit:
ich hab jetzt mal den "Buch-ID"-Lösch-Block auskommentiert und den nächsten Löschblock (Tags werden gelöscht - unnötige). EXAKT das gleiche Problem (es wird wieder die temp_delete_books genommen [truncate!], eingelesen, abgeglichen, trotz 0 übereinstimmungen wird gelöscht).

Irgendwas scheint daher mit meiner DB nicht zu stimmen. Das Script hat ja gut funktioniert. Von jetzt auf gleich kam das Problem erst (ich hatte nichts mehr am Import-Script geändert). Ich kann das Problem nur leider händisch null nachvollziehen. IMMER in die temp_delete_books voll und stimmt exakt mit der abzugleichenden mySQL-DB überein. So das mein SELECT immer 0 treffer ausgibt (was richtig ist => "nichts zu korrigieren")

Drehe hier noch am Rad :(
 
Zuletzt bearbeitet:
ich glaub zwar nicht dass das die Lösung ist, aber...
Code:
$delCount += 1;
kenne ich gar nicht.

Kenne das nur so:
Code:
$delCount++;
 
kommt aufs gleiche raus. ++ ist etwas "kürzer ;) und sieht schöner aus (ändere ich mal beim nächsten Script-Optimieren). Aber ne das ist es nicht. Ist nur eine Zählvariable um zu ermitteln wieviel gelöscht/bearbeitet wurde. Es gibt dafür auch ein sql-Befehl - der zählt aber anders - mit Variable arbeiten ist da (für MEINEN Zweck) genauer.

Ich hab den Fehler gefunden :( Das Zufällig kam mir so komisch vor ... Es wird ohne Logik gelöscht. Naja ... wenn man in einem anderen Script die gleiche temp_delete_book-Tabelle nutzt - etwas reinschreibt, truncate ausführt ... während das Import-Script noch arbeitet ... zieht man dem Import-/Aufräum-Script natürlich IDs weg => folge => mein mySQL-Datenbestand != Calibre -> löschen .... argh ... klassischer Layer8 :( Finde es aber faszinierend: ich suche den Fehler seit mehreren Stunden - über paar Tage verteilt - dann suche ich Hilfe und schwupp kommt die Eingebung: ich hatte gerade mehrere Blöcke vom "mysql....delete" befreit (#) ... also "trockener" Durchlauf. Und? In meinem anderen Script änderten sich paar Zahlen ("hä?! Das Import-Script schreibt doch gerade nicht! Was geht da?!") auf extrem hoch ( 200.000 Buchseiten in 2 Monaten gelesen - Respekt *G*) ...

Merke: Temp-Tabellen die schon "delete" im Namen haben, auch nur für passende Scripte nutzen ... :) [besser gar keine solche Tabellen nutzen - arbeite ich dran; sind dann nur extrem verschachtelte selects; temp-Tabelle im Arbeitsspeicher fand ich da elegantere Zwischenlösung]
 
Zurück
Oben