當前位置: 首頁> 最新文章列表> 如何使用PDOStatement::rowCount 獲取合併查詢的結果

如何使用PDOStatement::rowCount 獲取合併查詢的結果

gitbox 2025-05-28

在PHP 開發中,使用PDO 進行數據庫操作是推薦的方式之一。 PDOStatement::rowCount()是PDO 提供的一個方法,用於返回受前一次SQL 語句影響的行數。但它的行為在不同的SQL 語句類型中略有差異,特別是在執行SELECTUPDATEDELETEUNION查詢時,更需要理解其背後的機制。

本文將介紹PDOStatement::rowCount()的基本用法,並深入探討它在處理UNION合併查詢結果時的表現,以及正確統計合併結果行數的方法。

一、PDOStatement::rowCount() 的基本用法

在執行DELETEINSERTUPDATE時, 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 查詢中正確獲取結果行數

如果你使用的是SELECT查詢並想要獲取結果行數,推薦的方法是獲取所有結果後通過count()計算,例如:

 <?php
$stmt = $pdo->query("SELECT * FROM articles WHERE category = 'php'");
$results = $stmt->fetchAll();

echo "共有 " . count($results) . " 條記錄。";
?>

三、使用UNION 查詢時的行數問題

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查詢不支持返回結果行數。

正確方法:fetchAll + count

 <?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 時獲取行數

當你使用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查詢結果很多並需要分頁處理,可以將整個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()是獲取查詢行數更通用可靠的方法。

  • 對於UNIONUNION ALL查詢,同樣建議使用fetchAll()後統計數組長度來獲取總行數。

  • 如果需要分頁處理合併查詢,可以將UNION結果作為子查詢處理。

希望本文能幫助你更清楚地理解rowCount()的使用場景,避免在統計UNION查詢結果行數時踩坑。如果你正在構建API 或數據分析平台(比如在gitbox.net的項目中),這些技巧尤為重要。

需要我也幫你寫一下分頁的封裝函數嗎?