在使用PHP 的PDO(PHP Data Objects)擴展操作數據庫時,開發者常常依賴PDOStatement::rowCount()方法來獲取受影響的行數。然而,很多人在實際開發中會發現:這個方法在某些數據庫驅動中似乎並不能返回正確的結果,甚至在執行SELECT 查詢時直接返回0。這到底是為什麼呢?本文將深入解析這個問題。
PDOStatement::rowCount()是PDO 提供的一個方法,用於返回上一次執行的SQL 語句所影響的行數。它最常用於如下兩種類型的SQL 操作:
UPDATE 、 DELETE 、 INSERT等會修改數據的操作
SELECT查詢(某些驅動支持)
基本用法示例:
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'password');
$stmt = $pdo->prepare("DELETE FROM users WHERE status = :status");
$stmt->execute([':status' => 'inactive']);
echo $stmt->rowCount(); // 輸出受影響的行數
根據官方文檔, rowCount()在某些數據庫驅動中並不支持對SELECT查詢返回受影響行數,最典型的例子就是MySQL。在使用MySQL 的PDO 驅動時,執行SELECT 查詢後,調用rowCount()通常會返回0,而不是預期的結果數。
原因是:對於SELECT 查詢,MySQL 的客戶端庫不會告知受影響的行數,除非使用mysqlnd驅動(PHP 5.3+ 默認啟用)。即使如此,也不能完全依賴rowCount() 。
如果你真的需要獲取SELECT 查詢結果的數量,更安全的方式是使用fetchAll()然後用count()統計:
$stmt = $pdo->query("SELECT * FROM users WHERE status = 'active'");
$results = $stmt->fetchAll();
echo count($results);
雖然這會消耗更多內存,但可以確保准確性。
以下是幾個常見數據庫中, rowCount()的支持情況:
資料庫 | 是否支持SELECT 使用rowCount() |
---|---|
MySQL | ? 通常不支持(除非mysqlnd) |
PostgreSQL | ? 支持 |
SQLite | ? 通常不支持SELECT 查詢 |
MSSQL / SQLSRV | ? 支持 |
Oracle | ? 支持 |
因此,你在使用rowCount()時,應根據目標數據庫做出判斷。
避免依賴rowCount() 判斷SELECT 查詢是否有結果。最好是使用fetch()或fetchAll() ,根據是否返回數據來判斷是否有結果。
在DELETE/UPDATE/INSERT 中,rowCount() 通常是可靠的。只要查詢成功,它通常能返回受影響的行數。
確保啟用了mysqlnd(MySQL Native Driver)時再使用rowCount() 獲取SELECT 數量。
你可以通過phpinfo()或運行如下代碼查看是否使用mysqlnd:
echo phpinfo();
或者:
echo (extension_loaded('mysqlnd')) ? 'mysqlnd loaded' : 'mysqlnd not loaded';
PDOStatement::rowCount()雖然是一個方便的方法,但它的行為依賴於底層數據庫驅動的支持程度。為了確保代碼的跨數據庫兼容性,建議在使用SELECT 查詢時避免使用rowCount() ,改用更穩定可靠的方式來判斷數據行數。
更多數據庫相關教程請訪問: https://gitbox.net/dev/database-tutorials