PDO mysql: Wie kann man feststellen, ob das Einfügen erfolgreich war?


96

Ich benutze PDO, um einen Datensatz einzufügen (MySQL und PHP)

$stmt->bindParam(':field1', $field1, PDO::PARAM_STR);
$stmt->bindParam(':field2', $field2, PDO::PARAM_STR);
$stmt->execute();

Gibt es eine Möglichkeit festzustellen, ob es erfolgreich eingefügt wurde, z. B. wenn der Datensatz nicht eingefügt wurde, weil es sich um ein Duplikat handelte?

Bearbeiten: Natürlich kann ich mir die Datenbank ansehen, aber ich meine programmatisches Feedback.

Antworten:


140

PDOStatement->execute()gibt bei Erfolg true zurück. Dort PDOStatement->errorCode()können Sie auch nach Fehlern suchen.


1
Wie sehen Sie den Wert execute ()?
Malve

29
Nicht mehr so, $ value = $ stmt-> execute (); if ($ value) {// true} else {// false}
Ólafur Waage

23
Oder Sie können einfach tunif ($stmt->execute()) { //true }
Gavin

2
Ist PDOStatement->execute()und PDOStatement->errorCode()völlig im Einklang miteinander? Gibt es Umstände, unter denen PDOStatement->errorCode()etwas PDOStatement->execute()wahr ist? Oder wenn PDOStatement->execute()falsch zurückgegeben wird, aber PDOStatement->errorCode()nichts hat?
Datasn.io

1
Aber INSERT IGNORE würde auch dann true zurückgeben, wenn kein neuer Datensatz eingefügt wurde
Koffeehaus

24

Da die meisten empfohlenen Fehlermodus für PDO ist ERRMODE_EXCEPTION, keine direkte execute()Ergebnis Überprüfung wird immer Arbeit . Da die Codeausführung nicht einmal die in anderen Antworten angegebene Bedingung erreicht.

Es gibt also drei mögliche Szenarien, um das Ergebnis der Abfrageausführung in PDO zu verarbeiten:

  1. Um den Erfolg zu beurteilen, ist keine Überprüfung erforderlich. Bleiben Sie einfach bei Ihrem Programmablauf.
  2. Um den unerwarteten Fehler zu behandeln, bleiben Sie dabei - es ist kein sofortiger Behandlungscode erforderlich. Im Falle eines Datenbankfehlers wird eine Ausnahme ausgelöst, die an den standortweiten Fehlerbehandler weitergeleitet wird, der schließlich zu einer allgemeinen 500-Fehlerseite führt.
  3. Verwenden Sie einen try..catchOperator, um den erwarteten Fehler wie einen doppelten Primärschlüssel zu behandeln, und wenn Sie ein bestimmtes Szenario haben, um diesen bestimmten Fehler zu behandeln .

Für einen normalen PHP-Benutzer klingt es ein bisschen fremd - wie ist das, um das direkte Ergebnis der Operation nicht zu überprüfen? - aber genau so funktionieren Ausnahmen - Sie überprüfen den Fehler woanders. Ein für alle Mal. Sehr praktisch.

Kurz gesagt: In einem normalen Code benötigen Sie überhaupt keine Fehlerbehandlung. Behalten Sie einfach Ihren Code wie er ist:

$stmt->bindParam(':field1', $field1, PDO::PARAM_STR);
$stmt->bindParam(':field2', $field2, PDO::PARAM_STR);
$stmt->execute();
echo "Success!"; // whatever

Bei Erfolg wird dies angezeigt. Bei einem Fehler wird die reguläre Fehlerseite angezeigt, die Ihre Anwendung für einen solchen Anlass anzeigt.

Nur für den Fall, dass Sie ein anderes Behandlungsszenario haben als nur den Fehler zu melden, fügen Sie Ihre Einfügeanweisung in einen try..catchOperator ein, prüfen Sie, ob es sich um den erwarteten Fehler handelt, und behandeln Sie ihn. oder - wenn der Fehler anders war - die Ausnahme erneut auslösen , um die übliche Behandlung durch den standortweiten Fehlerbehandler zu ermöglichen. Unten finden Sie den Beispielcode aus meinem Artikel zur Fehlerbehandlung mit PDO :

try {
     $pdo->prepare("INSERT INTO users VALUES (NULL,?,?,?,?)")->execute($data);
} catch (PDOException $e) {
    if ($e->getCode() == 1062) {
        // Take some action if there is a key constraint violation, i.e. duplicate name
    } else {
        throw $e;
    }
}
echo "Success!";

Im obigen Code prüfen wir, ob der bestimmte Fehler eine Aktion ausführt, und lösen die Ausnahme für jeden anderen Fehler (z. B. keine solche Tabelle) erneut aus, der einem Programmierer gemeldet wird.

Während noch einmal - nur um einem Benutzer etwas wie "Ihre Einfügung war erfolgreich" zu sagen , wird nie eine Bedingung benötigt.


Was bedeutet "Erfolg"? Bedeutet das, dass eine neue Zeile eingefügt wurde, oder bedeutet dies, dass kein Fehler vorliegt?
Martin AJ

Für die INSERT-Abfrage ist es ziemlich dasselbe.
Ihr gesunder Menschenverstand

Sie haben Recht. Können Sie mir bitte sagen, was ist mit der query()Funktion? Kann ich query()anstelle von try-catch verwenden prepared()->execute()?
Martin AJ

3
Sie sollten query () niemals für Einfügungen verwenden. Einfügen bedeutet, dass Eingaben vorhanden sind, und Inpout bedeutet, dass diese vorbereitet werden sollten.
Ihr gesunder Menschenverstand

1
Mit MySQL musste ich überprüfen, ob $ e-> errorInfo [1] == 1062, um zu überprüfen, ob das Einfügen fehlgeschlagen ist, da $ e-> getCode () immer 23000 ist.
tronman


9

Wenn eine Aktualisierungsabfrage mit Werten ausgeführt wird, die mit dem aktuellen Datenbankeintrag übereinstimmen, $stmt->rowCount()wird zurückgegeben, da 0keine Zeilen betroffen waren. Wenn Sie einen if( rowCount() == 1 )Test auf Erfolg durchführen müssen, denken Sie, dass die Aktualisierung fehlgeschlagen ist, wenn sie nicht fehlgeschlagen ist, aber die Werte bereits in der Datenbank vorhanden waren, sodass sich nichts ändert.

$stmt->execute();
if( $stmt ) return "success";

Dies funktionierte bei mir nicht, als ich versuchte, einen Datensatz mit einem eindeutigen Schlüsselfeld zu aktualisieren, gegen das verstoßen wurde. Die Abfrage hat Erfolg zurückgegeben, aber eine andere Abfrage gibt den alten Feldwert zurück.


3
Wenn Sie den Datensatz einfügen müssen, überprüfen Sie ihn am besten wie folgt ............................. ..... .................. if($stmt->execute() && ($stmt->rowCount()>0))
jave.web

4

Sie können die Zeilenanzahl testen

    $sqlStatement->execute( ...);
    if ($sqlStatement->rowCount() > 0)
    {
        return true;
    }

Ein Verweis zurück auf die Dokumente ist immer hilfreich @YourCommonSense. Darin heißt es: "Dieses Verhalten ist nicht für alle Datenbanken garantiert und sollte nicht für tragbare Anwendungen verwendet werden." Es kann jedoch erstens ausgewählt und zweitens für MySQL unterstützt werden, das Gegenstand dieses Beitrags ist.
Crafter

Geben Sie einfach "pdo rowcount" in die Adressleiste Ihres Browsers ein und klicken Sie auf den ersten Link. Es dauert weniger Eingabe als ein Kommentar
Ihr gesunder Menschenverstand

1
@crafter Richtig. Es heißt, dass rowCount () für SELECTAbfragen nicht zuverlässig sein kann (und selbst dort sprechen die Dokumente über mehrere Abfragen). Es sagt nichts über DELETE, INSERToder UPDATE, was in Ordnung zu Arbeit zu sein scheint (die Frage war , um eine INSERTAbfrage). Ich bin jedoch neu bei PDO und wenn ich falsch liege und jemand andere Referenzen hat, schreibe sie bitte hier. Ich bin interessiert zu sehen, ob es echte Nachteile für die 3 obigen Befehle gibt.
StanE

1

Verwenden Sie id als Primärschlüssel mit automatischer Inkrementierung

$stmt->execute();
$insertid = $conn->lastInsertId();

Die inkrementelle ID ist auch beim ersten Datensatz immer größer als Null. Dies bedeutet, dass immer ein wahrer Wert für die ID zurückgegeben wird, da größer als Null in PHP true bedeutet

if ($insertid)
   echo "record inserted successfully";
else
   echo "record insertion failed";

Was ist, wenn ich kein automatisch inkrementiertes Feld in meiner Tabelle benötige?
Ihr gesunder Menschenverstand

Wer dun? Sie? Mit der RESTFul-API, die so häufig verwendet wird, ist die automatische Inkrement-ID obligatorisch.
Jumper RBB

Warum sollte jemand kein primäres und automatisches Inkrement oder eine andere Sequenzspalte haben? Wenn eine Überprüfungsmethode erforderlich ist, fügen Sie eine beliebige sequentielle Spalte hinzu. Wenn diese Lösung nicht für Sie ist, fügen Sie sie nicht hinzu. Für mich ist das in Ordnung. Ich verwende immer eine Spalte mit sequentiellen und automatischen Inkrementen, sodass ich immer die Möglichkeit habe, zu testen, ob meine Abfrage erfolgreich war.
Samuel Ramzan

0

PDOStatement-> execute () kann eine Ausnahme auslösen

Was Sie also tun können, ist

try
{
PDOStatement->execute();
//record inserted
}
catch(Exception $e)
{
//Some error occured. (i.e. violation of constraints)
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.