Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] SQLite führt Commit nicht aus

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Erledigt] SQLite führt Commit nicht aus

    Hallo Leute.
    Ich bin hier grad am verzweifeln.
    Ich hab hier ein Skript, welches mir mehrere Einträge aus einer Datenbank löschen soll.

    Da die zu löschenden Teile zusammengehören und ich sicherstellen will, daß die Teile auch alle gelöscht werden, mach ich ne Transaktion um die SQL-Queries.

    Im Code sieht das etwa wie folgt aus:
    Code:
    $db = new PDO("sqlite:database.db");
    if ($db->beginTransaction())
        echo "Begin";
    else
        echo "No Begin";
    
    $error = false;
    
    $SQL = "SELECT * FROM Table;";
    $result = $db->query($SQL);
    while ($row=$result->fetch(PDO::FETCH_BOTH))
    {
        $SQL2 = "DELETE FROM TABLE WHERE spalte = ".$row[0].";";
        $result2 = $db->query($SQL2);
        if (($error = $db->errorCode) != "00000")
        {
    	echo "Fehler<br>";
    	$error = true;
        }
    }
    if ($error)
    {
        $db->rollback();
        echo "rollback";
    }
    else
    {
        if ($db->commit())
            echo"commit";
        else
            echo "No commit";
    }
    Das scheint im Prinzip auch gut zu klappen, die errorvariable wird nicht gesetzt. Allerdings tritt bei Ausführen von commit ein Fehler auf, denn ich bekomme immer "No commit" zur Antwort.

    Ist hier vielleicht die Menge der DELETE-Anweisungen ausschlaggebend? Diese können schonmal ein paar hundert erreichen.

    Hab ich vielleicht ein Problem mit dem Errorhandling, daß er mir trotz error nicht in den Rollback Zweig geht?

    Wär schön, wenn mir einer von euch weiterhelfen könnte.

    LG,
    MSJones

    PS: Wenn ich mir sämtliche SQL-Anweisungen ausgeben lasse und diese in eine TXT-Datei kopiere und entsprechen noch BEGIN; davor und COMMIT; dahinterschreibe, funktioniert es, wenn ich die Datei direkt ins SQLite importiere.


  • #2
    Zitat von MSJones Beitrag anzeigen
    Im Code sieht das etwa wie folgt aus:
    Code:
    $db = new PDO("sqlite:database.db");
    if ($db->beginTransaction();)
        echo "Begin";
    else
        echo "No Begin";
    
    $error = false;
    
    $SQL = "SELECT * FROM Table;"
    $result = $db->query($SQL);
    while $row=$result->fetch(PDO::FETCH_BOTH)
    {
        $SQL2 = "DELETE FROM TABLE WHERE spalte = ".$row[0].";"
        if (($error = $db->errorCode) != "00000")
        {
    	echo "Fehler<br>";
    	$error = true;
        }
    if ($error)
    {
        $db->rollback();
        echo $rollback
    }
    else
    {
        if ($db->commit())
            echo"commit";
        else
            echo "No commit";
    }
    In etwa? Der Code da oben ist an mehreren Stellen fehlerhaft - über was sollen wir nun diskutieren, den fehlerhaften, geposteten Code oder über Symptome und Annahmen zu deinem wirklichen Code (den wir nicht kennen)?

    Zu der Menge der Delete Anweisungen: Du könntest die zu löschenden IDs sammeln und später mit einer IN-Abfrage erledigen: DELETE FROM .. WHERE ID IN (Liste der zu löschenden IDs)
    Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

    Kommentar


    • #3
      Hallo.
      Das in etwa kommt daher, daß die wirkliche Code recht komplex ist und sich über mehrere Dateien aufspaltet, die sich untereinander mit require("xx") einbinden.

      Daher hab ich die meiner Meinung nach wichtigen Stellen herausgenommen und in diesen "In etwa" Code gepostet.

      Vom Syntax her ist mein tatsächlicher Code richtig, sonst würd ich ja Fehlermeldungen bekommen. In diesem In Etwa Code kanns durchaus sein, daß da noch der ein oder andere Fehler drin ist. Hab z.B. grad beim beginTransaction den falschen Strichpunkt entdeckt.

      Die Menge der DELETES läßt sich leider auch nicht so wirklich verkleinern, da das über mehrere Tabellen läuft, die von einander abhängig sind und die Kriterien auch immer unterschiedlich sind. Das würd ne zu komplexe SQL Anweisung geben für meinen Geschmack.
      Kann denn die Menge von Anweisungen so ein Problem verursachen?

      Mal abgesehen, von kleineren Syntaxfehlern: Isst denn die Errorbehandlung in meinem obigen Beispiel korrekt? Oder mach ich dabei grundsätzlich was falsch?

      Kommentar


      • #4
        Ich kenne SQLite nicht besonders, aber mir fallen zwei Sachen auf.

        a) Der Datenbank-Connection $db liest den Result des SELECT, anschließend wird mit $db eine Commit() durchgeführt. Damit ist vermutlich der ResultSet hinter $db nicht mehr da. Für den DELETE wird somit eine zweite Datenbankverbindung $dbDelete notwendig.

        b) Anstatt mit einer Schleife zu löschen, geht dass ja auch auf einmal. Sinngemäß so:

        Code:
        DELETE FROM tabelle
         WHERE id IN ( SELECT id FROM tabelle WHERE x = 1);
        Grüße
        Thomas

        Kommentar


        • #5
          So, ich hab das Problem endlich gelöst.

          Wenn ich mit ResultSets arbeite, muß ich diese vor dem Commit schließen mit "$result = null;" in meinem Fall.
          Dann wird richtig commited...

          Kommentar

          Lädt...
          X