Lors de l'utilisation de PDO de PHP (objets de données PHP) pour le développement de la base de données, Pdostatement :: RowCount () est souvent utilisé pour obtenir le nombre de lignes affectées par la requête, en particulier après avoir exécuté la mise à jour , la suppression et d'autres instructions. Cependant, dans certains scénarios, ses résultats de retour peuvent sembler "trompeuses" ou même buggy.
Cet article approfondira pourquoi RowCount () n'est parfois pas comme nous nous attendions, révélant les raisons derrière cela et donnant la bonne façon de le gérer.
$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(); // Sortie le nombre de lignes supprimées
Dans ce code, nous avons supprimé un enregistrement et espérons savoir via RowCount () que plusieurs enregistrements sont affectés. Cela fonctionne généralement bien pour les instructions de suppression et de mise à jour . Cependant, une fois que des instructions sélectionnées ou certaines situations spéciales sont impliquées, le problème se pose.
Bien que RowCount () soit pris en charge pour sélectionner les requêtes par certaines bases de données telles que PostgreSQL, appeler RowCount () après sélection dans MySQL renvoie généralement 0 . La raison en est que PDO utilise MySQL_ATTR_USE_BUFFERED_QUERY par défaut dans MySQL. Les lignes sont extraites avec retard et RowCount ne peut pas connaître avec précision le nombre de lignes.
$stmt = $pdo->query("SELECT * FROM users");
echo $stmt->rowCount(); // exister MySQL Sortie possible 0
Même si l'instruction est exécutée légalement, tant qu'il n'y a pas de changement réel dans la base de données, RowCount () renvoie 0. Par exemple:
$stmt = $pdo->prepare("UPDATE users SET name = :name WHERE id = :id");
$stmt->execute([':name' => 'Alice', ':id' => 123]);
echo $stmt->rowCount(); // si name Déjà Alice,Puis retourner 0
Ce n'est pas une erreur, mais une caractéristique de SQL: sans modifications réelles, elle ne compte pas comme «influence» la ligne.
Différentes implémentations du pilote de base de données prennent en charge RowCount () de manière incohérente. Par exemple:
MySQL: SELECT ne renvoie pas la valeur correcte, la mise à jour / supprimer la prend en charge.
PostgreSQL: La plupart des instructions le soutiennent.
SQLITE: La plupart des instructions le soutiennent.
Oracle: Le comportement est plus compliqué et vous devez être utilisé avec prudence.
$stmt = $pdo->query("SELECT * FROM users WHERE status = 'active'");
$rows = $stmt->fetchAll();
echo count($rows);
Ou utilisez la traversée:
$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(); // Seulement quand name Revenir au changement réel 1
Dans de nombreux cas, en particulier dans les requêtes ou les opérations par lots, il est préférable de laisser SQL renvoyer directement le nombre de lignes affectées:
$stmt = $pdo->query("SELECT COUNT(*) FROM users WHERE status = 'active'");
$count = $stmt->fetchColumn();
echo $count;
Ne supposez jamais que tous les conducteurs se comportent régulièrement. Vous pouvez utiliser les méthodes suivantes pour détecter ou définir la compatibilité lors de l'initialisation de l'APD:
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password', [
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
]);
Bien que Pdostatement :: RowCount () soit une interface couramment utilisée, elle n'agit pas toujours comme vous le souhaitez dans différentes bases de données et différents types SQL. En tant que développeur, comprendre sa portée et ses limites est la clé pour éviter les pièges.
La stratégie la plus sûre est:
Évitez de compter sur RowCount () dans SELECT QUIRES;
Pour les opérations telles que la mise à jour / supprimer , il est entendu que "affectant les lignes" n'est pas "trouver des lignes";
Pour un contrôle précis ou une compatibilité en database transversale, envisagez d'utiliser la logique de comptage de niveau SQL.