在PHP 開發中,使用PDO 進行數據庫操作是推薦的方式之一。 PDOStatement::rowCount()是PDO 提供的一個方法,用於返回受前一次SQL 語句影響的行數。但它的行為在不同的SQL 語句類型中略有差異,特別是在執行SELECT 、 UPDATE 、 DELETE和UNION查詢時,更需要理解其背後的機制。
本文將介紹PDOStatement::rowCount()的基本用法,並深入探討它在處理UNION合併查詢結果時的表現,以及正確統計合併結果行數的方法。
在執行DELETE 、 INSERT或UPDATE時, rowCount()可以返回受影響的行數。示例如下:
<?php
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'pass');
$stmt = $pdo->prepare("UPDATE users SET status = 'active' WHERE last_login > NOW() - INTERVAL 30 DAY");
$stmt->execute();
echo "更新了 " . $stmt->rowCount() . " 行記錄。";
?>
在上面的代碼中, rowCount()返回的是被更新的行數。
但當執行SELECT查詢時, rowCount()並不是總能按預期工作。對大多數數據庫(尤其是MySQL),默認的PDO::MYSQL_ATTR_USE_BUFFERED_QUERY設置下, rowCount()在SELECT查詢中並不會返回結果行數,而是返回0。
如果你使用的是SELECT查詢並想要獲取結果行數,推薦的方法是獲取所有結果後通過count()計算,例如:
<?php
$stmt = $pdo->query("SELECT * FROM articles WHERE category = 'php'");
$results = $stmt->fetchAll();
echo "共有 " . count($results) . " 條記錄。";
?>
UNION是SQL 中用於合併兩個或多個SELECT查詢結果的語法。默認情況下,它會去除重複行(如需保留重複行可使用UNION ALL )。那麼,如何通過PDO 獲取UNION查詢結果的行數呢?
錯誤示範:
<?php
$stmt = $pdo->query("SELECT name FROM authors UNION SELECT name FROM editors");
echo $stmt->rowCount(); // 在大多數 MySQL 情況下會返回 0
?>
這是因為rowCount()在MySQL 中對SELECT查詢不支持返回結果行數。
<?php
$stmt = $pdo->query("
SELECT name FROM authors
UNION
SELECT name FROM editors
");
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo "合併查詢後共有 " . count($rows) . " 條記錄。";
?>
這個方法通過fetchAll()獲取了所有結果,然後用count()統計行數,既能正確獲取UNION查詢的合併結果數,也能適用於其他復雜的SELECT查詢。
當你使用UNION ALL (不去重)時,同樣可以用相同方法獲取所有記錄數:
<?php
$stmt = $pdo->query("
SELECT name FROM authors
UNION ALL
SELECT name FROM editors
");
$rows = $stmt->fetchAll();
echo "UNION ALL 查詢結果行數為:" . count($rows);
?>
若你的UNION查詢結果很多並需要分頁處理,可以將整個UNION查詢當作子查詢來處理分頁:
<?php
$page = 1;
$limit = 10;
$offset = ($page - 1) * $limit;
$sql = "
SELECT * FROM (
SELECT name FROM authors
UNION
SELECT name FROM editors
) AS combined
LIMIT :limit OFFSET :offset
";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
$results = $stmt->fetchAll();
foreach ($results as $row) {
echo $row['name'] . "<br>";
}
?>
PDOStatement::rowCount()對於SELECT語句(尤其在MySQL)通常不能返回有效結果。
使用fetchAll() + count()是獲取查詢行數更通用可靠的方法。
對於UNION或UNION ALL查詢,同樣建議使用fetchAll()後統計數組長度來獲取總行數。
如果需要分頁處理合併查詢,可以將UNION結果作為子查詢處理。
希望本文能幫助你更清楚地理解rowCount()的使用場景,避免在統計UNION查詢結果行數時踩坑。如果你正在構建API 或數據分析平台(比如在gitbox.net的項目中),這些技巧尤為重要。
需要我也幫你寫一下分頁的封裝函數嗎?