Bei der Verwendung von PHP -PDO (PHP -Datenobjekte) für die Datenbankentwicklung wird PDOSTATEMENT :: rowCount () häufig verwendet, um die Anzahl der von der Abfrage betroffenen Zeilen zu erhalten, insbesondere nach der Ausführung von Aktualisierung , Löschen und anderen Anweisungen. In einigen Szenarien können sich seine Rückkehrergebnisse jedoch "irreführend" oder sogar fehlerhaft anfühlen.
In diesem Artikel wird ein tieferer, warum RowCount () manchmal nicht so ist, wie wir es erwartet haben, und zeigt die Gründe dafür und gibt den richtigen Weg, um damit umzugehen.
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
$stmt = $pdo->prepare("DELETE FROM users WHERE id = :id");
$stmt->execute([':id' => 123]);
echo $stmt->rowCount(); // Die Anzahl der gelöschten Linien ausgeben
In diesem Code haben wir einen Datensatz gelöscht und hoffen, über RowCount () zu wissen, dass mehrere Datensätze betroffen sind. Dies funktioniert normalerweise gut für Löschen und Aktualisierungen . Sobald es jedoch ausgewählte Aussagen oder einige besondere Situationen beteiligt sind, stellt sich das Problem auf.
Obwohl RowCount () für ausgewählte Abfragen von einigen Datenbanken wie PostgreSQL unterstützt wird, wird das Aufrufen von RowCount () nach Auswahl in MySQL normalerweise 0 zurückgegeben . Der Grund dafür ist, dass PDO in MySQL standardmäßig mySQL_ATTR_USE_BUFFERREERD_QUEY verwendet. Die Zeilen werden verzögert und RowCount kann die Anzahl der Zeilen nicht genau kennen.
$stmt = $pdo->query("SELECT * FROM users");
echo $stmt->rowCount(); // existieren MySQL Mögliche Ausgabe 0
Auch wenn die Anweisung legal ausgeführt wird, kehrt RowCount () 0 zurück.
$stmt = $pdo->prepare("UPDATE users SET name = :name WHERE id = :id");
$stmt->execute([':name' => 'Alice', ':id' => 123]);
echo $stmt->rowCount(); // Wenn name Bereits Alice,Dann kehren Sie zurück 0
Dies ist kein Fehler, sondern ein Merkmal von SQL: Ohne tatsächliche Änderungen gilt es nicht als "Einfluss" die Zeile.
Verschiedene Datenbanktreiber -Implementierungen unterstützen RowCount () inkonsistent. Zum Beispiel:
MySQL: SELECT gibt nicht den richtigen Wert zurück, aktualisiert/löschen unterstützt ihn.
PostgreSQL: Die meisten Aussagen unterstützen es.
SQLite: Die meisten Aussagen unterstützen es.
Oracle: Das Verhalten ist komplizierter und Sie müssen mit Vorsicht verwendet werden.
$stmt = $pdo->query("SELECT * FROM users WHERE status = 'active'");
$rows = $stmt->fetchAll();
echo count($rows);
Oder verwenden Sie Traversal:
$count = 0;
foreach ($stmt as $row) {
$count++;
}
echo $count;
$stmt = $pdo->prepare("UPDATE users SET name = :name WHERE id = :id AND name != :name");
$stmt->execute([':name' => 'Alice', ':id' => 123]);
echo $stmt->rowCount(); // Nur wann name Kehren Sie zur tatsächlichen Änderung zurück 1
In vielen Fällen, insbesondere in Abfragen oder Stapeloperationen, ist es besser, SQL die Anzahl der betroffenen Zeilen direkt zurückzugeben:
$stmt = $pdo->query("SELECT COUNT(*) FROM users WHERE status = 'active'");
$count = $stmt->fetchColumn();
echo $count;
Gehen Sie niemals davon aus, dass sich alle Fahrer konsequent verhalten. Sie können die folgenden Methoden verwenden, um die Kompatibilität beim Initialisieren von PDO zu erkennen oder festzulegen:
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password', [
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
]);
Obwohl pdostatement :: rowCount () eine häufig verwendete Schnittstelle ist, wirkt sie nicht immer so, wie Sie in verschiedenen Datenbanken und verschiedenen SQL -Typen wünschen. Als Entwickler ist das Verständnis des Umfangs und seiner Einschränkungen der Schlüssel zur Vermeidung von Fallstricken.
Die sicherste Strategie ist:
Vermeiden Sie es, sich in ausgewählten Abfragen auf RowCount () zu verlassen.
Für Operationen wie Update/Löschen wird davon ausgegangen, dass "Zeilen" nicht "Zeilen finden" sind.
Für eine präzise Steuerung oder die Kompatibilität für Cross-Database-Kompatibilität sollten Sie die Zähllogik auf SQL-Ebene verwenden.