215

周围有许多相互矛盾的说法。在 PHP 中使用 PDO 获取行数的最佳方法是什么?在使用 PDO 之前,我只是简单地使用了mysql_num_rows.

fetchAll是我不想要的东西,因为我有时可能会处理大型数据集,所以不适合我的使用。

你有什么建议吗?

4

24 回答 24

296
$sql = "SELECT count(*) FROM `table` WHERE foo = ?"; 
$result = $con->prepare($sql); 
$result->execute([$bar]); 
$number_of_rows = $result->fetchColumn(); 

这不是最优雅的方式,而且它涉及额外的查询。

PDO has PDOStatement::rowCount(),这显然在 MySql 中不起作用多么痛苦。

来自 PDO 文档:

对于大多数数据库,PDOStatement::rowCount() 不返回受 SELECT 语句影响的行数。相反,使用 PDO::query() 发出 SELECT COUNT(*) 语句,其谓词与预期的 SELECT 语句相同,然后使用 PDOStatement::fetchColumn() 检索将返回的行数。然后,您的应用程序可以执行正确的操作。

编辑:上面的代码示例使用准备好的语句,在许多情况下,这对于计算行数可能是不必要的,所以:

$nRows = $pdo->query('select count(*) from blah')->fetchColumn(); 
echo $nRows;
于 2009-05-19T15:16:13.767 回答
90

正如我之前在对类似问题的回答中所写的那样,唯一mysql_num_rows()有效的原因是因为它在内部获取所有行以向您提供该信息,即使您看起来并不喜欢它。

因此,在 PDO 中,您的选择是:

  1. 使用 PDO 的fetchAll()函数将所有行提取到一个数组中,然后count()在其上使用。
  2. SELECT COUNT(*)按照 karim79 的建议,对 进行额外查询。
  3. 使用 MySQL 的FOUND_ROWS()函数,除非查询有SQL_CALC_FOUND_ROWSLIMIT子句(在这种情况下,查询返回的行数和返回的行数FOUND_ROWS()可能不同)。但是,此功能已弃用,将来将被删除。
于 2009-05-19T15:39:51.093 回答
40

正如它经常发生的那样,这个问题令人困惑。人们来到这里有两个不同的任务:

  1. 他们需要知道表中有多少行
  2. 他们需要知道查询是否返回了任何行

这是两个完全不同的任务,它们没有任何共同之处,并且无法通过相同的功能来解决。具有讽刺意味的是,它们都不需要使用实际PDOStatement::rowCount()功能。

让我们看看为什么

计算表中的行数

在使用 PDO 之前,我只是简单地使用了mysql_num_rows().

表示你已经做错了。就消耗服务器资源而言,使用mysql_num_rows()rowCount()计算表中的行数是一场真正的灾难。数据库必须从磁盘读取所有行,消耗数据库服务器上的内存,然后将所有这些数据堆发送到 PHP,同时消耗 PHP 进程的内存,绝对没有理由给您的服务器增加负担。
此外,仅选择行来计算它们根本没有意义。必须count(*)改为运行查询。数据库将从索引中计算出记录,而不读取实际行,然后只返回一行

为此目的,接受的答案中建议的代码是公平的,除了它不是“额外”查询而是唯一要运行的查询这一事实。

计算返回的行数。

第二个用例不是灾难性的而是毫无意义的:如果您需要知道您的查询是否返回任何数据,您总是拥有数据本身!

比如说,如果您只选择一行。好的,您可以将获取的行用作标志:

$stmt->execute();
$row = $stmt->fetch();
if (!$row) { // here! as simple as that
    echo 'No data found';
}

如果您需要获取很多行,那么您可以使用fetchAll().

fetchAll()是我不想要的,因为我有时可能会处理大型数据集

是的,当然,对于第一个用例,情况会差一倍。但正如我们已经了解到的那样,不要只选择行来计算它们,无论是 withrowCount()还是fetchAll().

但是,如果您要实际使用选定的行,使用fetchAll(). 请记住,在 Web 应用程序中,您永远不应该选择大量的行。只应选择将在网页上实际使用的行,因此您必须使用LIMIT,WHERE或 SQL 中的类似子句。而对于这样一个中等数量的数据,它是可以使用的fetchAll()。同样,只需在条件中使用此函数的结果:

$stmt->execute();
$data = $stmt->fetchAll();
if (!$data) { // again, no rowCount() is needed!
    echo 'No data found';
}

当然,运行一个额外的查询只是为了判断您的其他查询是否返回任何行,这将是绝对疯狂的,正如它在两个最佳答案中所建议的那样。

计算大型结果集中的行数

在这种罕见的情况下,当您需要选择大量的行(例如在控制台应用程序中)时,您必须使用无缓冲查询,以减少使用的内存量。但这是实际情况,当rowCount() 将不可用时,因此也没有使用此功能。

因此,这是您可能需要运行额外查询的唯一用例,以防您需要知道所选行数的接近估计值。

于 2013-05-27T16:00:21.977 回答
22

我最终使用了这个:

$result = $db->query($query)->fetchAll();

if (count($result) > 0) {
    foreach ($result as $row) {
        echo $row['blah'] . '<br />';
    }
} else {
    echo "<p>Nothing matched your query.</p>";
}
于 2011-07-31T17:05:48.097 回答
19

这已经很晚了,但我遇到了问题,我这样做了:

function countAll($table){
   $dbh = dbConnect();
   $sql = "select * from `$table`";

   $stmt = $dbh->prepare($sql);
    try { $stmt->execute();}
    catch(PDOException $e){echo $e->getMessage();}

return $stmt->rowCount();

这真的很简单,也很容易。:)

于 2013-03-06T07:02:56.687 回答
15

这篇文章很旧,但是使用 PDO 在 php 中获取行数很简单

$stmt = $db->query('SELECT * FROM table');
$row_count = $stmt->rowCount();
于 2014-07-23T00:31:06.740 回答
6

这是一篇旧帖子,但在寻找替代品时感到沮丧。非常不幸的是 PDO 缺乏这个特性,尤其是 PHP 和 MySQL 往往齐头并进。

使用 fetchColumn() 有一个不幸的缺陷,因为 fetchColumn() 将指针移动到下一行,因此您不能再(有效地)使用该结果集。因此,例如,如果您的结果类似于

  1. 水果->香蕉
  2. 水果->苹果
  3. 水果->橙子

如果你使用 fetchColumn() 你可以发现返回了 3 个水果,但是如果你现在循环结果,你只有两列, fetchColumn() 的价格是第一列结果的损失刚刚找到返回了多少行。这会导致编码草率,如果实施的话,会导致完全错误的结果。

因此,现在,使用 fetchColumn() 您必须实现全新的调用和 MySQL 查询才能获得新的工作结果集。(希望自您上次查询以来没有改变),我知道,不太可能,但它可能会发生。此外,所有行计数验证的双重查询的开销。对于这个例子来说,它很小,但是在连接查询中解析 200 万行,这不是一个令人愉快的代价。

我喜欢 PHP,并支持参与其开发的每个人以及整个社区每天使用 PHP,但我真的希望在未来的版本中解决这个问题。这“真的”是我对 PHP PDO 的唯一抱怨,否则它是一个很棒的课程。

于 2010-07-14T02:29:47.067 回答
5

回答这个问题是因为我现在知道这一点,也许它会很有用。

请记住,您不能两次获取结果。您必须将获取结果保存到数组中,通过 获取行数count($array),并使用 输出结果foreach。例如:

$query = "your_query_here";
$STH = $DBH->prepare($query);
$STH->execute();
$rows = $STH->fetchAll();
//all your results is in $rows array
$STH->setFetchMode(PDO::FETCH_ASSOC);           
if (count($rows) > 0) {             
    foreach ($rows as $row) {
        //output your rows
    }                       
}
于 2014-08-10T06:01:44.617 回答
3

如果您只想获取行数(而不是数据),即。在准备好的语句中使用 COUNT(*) 那么您需要做的就是检索结果并读取值:

$sql = "SELECT count(*) FROM `table` WHERE foo = bar";
$statement = $con->prepare($sql); 
$statement->execute(); 
$count = $statement->fetch(PDO::FETCH_NUM); // Return array indexed by column number
return reset($count); // Resets array cursor and returns first value (the count)

实际上检索所有行(数据)来执行简单计数是一种资源浪费。如果结果集很大,您的服务器可能会阻塞它。

于 2016-06-11T09:16:24.203 回答
3

看看这个链接: http ://php.net/manual/en/pdostatement.rowcount.php 不建议在 SELECT 语句中使用 rowCount() !

于 2017-04-13T04:19:34.603 回答
2

当涉及到 mysql 如何使用 PHP PDO计算或获取表中的行数时,我使用它

// count total number of rows
$query = "SELECT COUNT(*) as total_rows FROM sometable";
$stmt = $con->prepare($query);

// execute query
$stmt->execute();

// get total rows
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$total_rows = $row['total_rows'];

归功于 Mike@codeofaninja.com

于 2017-08-12T14:45:38.750 回答
1

要在查询中使用变量,您必须使用bindValue()or bindParam()。并且不要将变量与" . $variable . "

$statement = "SELECT count(account_id) FROM account
                  WHERE email = ? AND is_email_confirmed;";
$preparedStatement = $this->postgreSqlHandler->prepare($statement);
$preparedStatement->bindValue(1, $account->getEmail());
$preparedStatement->execute();
$numberRows= $preparedStatement->fetchColumn();

总帐

于 2018-12-07T23:44:07.813 回答
-1

一个快速的一个班轮让第一个条目返回。这对于非常基本的查询非常有用。

<?php
$count = current($db->query("select count(*) from table")->fetch());
?>

参考

于 2013-10-02T12:57:19.163 回答
-1

我尝试$count = $stmt->rowCount();使用 Oracle 11.2,但它不起作用。我决定使用如下所示的 for 循环。

   $count =  "";
    $stmt =  $conn->prepare($sql);
    $stmt->execute();
   echo "<table border='1'>\n";
   while($row = $stmt->fetch(PDO::FETCH_OBJ)) {
        $count++;
        echo "<tr>\n";
    foreach ($row as $item) {
    echo "<td class='td2'>".($item !== null ? htmlentities($item, ENT_QUOTES):"&nbsp;")."</td>\n";
        } //foreach ends
        }// while ends
        echo "</table>\n";
       //echo " no of rows : ". oci_num_rows($stmt);
       //equivalent in pdo::prepare statement
       echo "no.of rows :".$count;
于 2014-05-08T19:53:36.203 回答
-1

对于我想要特定行并想知道是否找到它的直接查询,我使用如下内容:

function fetchSpecificRow(&$myRecord) {
    $myRecord = array();
    $myQuery = "some sql...";
    $stmt = $this->prepare($myQuery);
    $stmt->execute(array($parm1, $parm2, ...));
    if ($myRecord = $stmt->fetch(PDO::FETCH_ASSOC)) return 0;
    return $myErrNum;
}
于 2016-01-30T23:33:14.283 回答
-1

最简单的方法,只有2行,

$sql = $db->query("SELECT COUNT(*) FROM tablename WHERE statement='condition'");
echo $sql->fetchColumn();
于 2021-04-01T06:30:49.537 回答
-2

当您在 mysql 语句中创建 COUNT(*) 时,例如

$q = $db->query("SELECT COUNT(*) FROM ...");

您的 mysql 查询已经在计算结果的数量 为什么要在 php 中再次计算?得到你的mysql的结果

$q = $db->query("SELECT COUNT(*) as counted FROM ...");
$nb = $q->fetch(PDO::FETCH_OBJ);
$nb = $nb->counted;

并将$nb包含您用 mysql 语句计算的整数,写起来有点长,但执行起来很快

编辑:抱歉发错了帖子,但是作为一些示例显示带有计数的查询,我建议使用 mysql 结果,但是如果您不使用 sql fetchAll() 中的计数,如果您将结果保存在变量中是有效的你不会松懈的。

$data = $dbh->query("SELECT * FROM ...");
$table = $data->fetchAll(PDO::FETCH_OBJ);

count($table)将返回行数,您仍然可以在喜欢$row = $table[0] 或使用之后使用结果foreach

foreach($table as $row){
  print $row->id;
}
于 2013-05-27T15:48:38.860 回答
-2

这是 PDO 类的定制扩展,具有帮助函数来检索最后一个查询的“WHERE”条件所包含的行数。

不过,您可能需要添加更多“处理程序”,具体取决于您使用的命令。现在它只适用于使用“FROM”或“UPDATE”的查询。

class PDO_V extends PDO
{
    private $lastQuery = null;

    public function query($query)
    {
        $this->lastQuery = $query;    
        return parent::query($query);
    }
    public function getLastQueryRowCount()
    {
        $lastQuery = $this->lastQuery;
        $commandBeforeTableName = null;
        if (strpos($lastQuery, 'FROM') !== false)
            $commandBeforeTableName = 'FROM';
        if (strpos($lastQuery, 'UPDATE') !== false)
            $commandBeforeTableName = 'UPDATE';

        $after = substr($lastQuery, strpos($lastQuery, $commandBeforeTableName) + (strlen($commandBeforeTableName) + 1));
        $table = substr($after, 0, strpos($after, ' '));

        $wherePart = substr($lastQuery, strpos($lastQuery, 'WHERE'));

        $result = parent::query("SELECT COUNT(*) FROM $table " . $wherePart);
        if ($result == null)
            return 0;
        return $result->fetchColumn();
    }
}
于 2013-07-15T08:32:20.307 回答
-2

您可以将最好的方法组合到一行或一个函数中,并为您自动生成新的查询:

function getRowCount($q){ 
    global $db;
    return $db->query(preg_replace('/SELECT [A-Za-z,]+ FROM /i','SELECT count(*) FROM ',$q))->fetchColumn();
}

$numRows = getRowCount($query);
于 2016-05-26T23:25:21.847 回答
-2
<table>
      <thead>
           <tr>
                <th>Sn.</th>
                <th>Name</th>
           </tr>
      </thead>
      <tbody>
<?php
     $i=0;
     $statement = $db->prepare("SELECT * FROM tbl_user ORDER BY name ASC");
     $statement->execute();
     $result = $statement->fetchColumn();
     foreach($result as $row) {
        $i++;
    ?>  
      <tr>
         <td><?php echo $i; ?></td>
         <td><?php echo $row['name']; ?></td>
      </tr>
     <?php
          }
     ?>
     </tbody>
</table>
于 2016-06-25T05:40:16.377 回答
-2
function count_x($connect) {  
 $query = "  SELECT * FROM tbl WHERE id = '0' ";  
 $statement = $connect->prepare($query);  $statement->execute();  
 $total_rows = $statement->rowCount();  
 return $total_rows; 
}
于 2018-04-11T06:22:05.577 回答
-2

有一个简单的解决方案。如果您使用 PDO 像这样连接到您的数据库:

try {

    $handler = new PDO('mysql:host=localhost;dbname=name_of_your_db', 'your_login', 'your_password'); 
    $handler -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

} catch (PDOException $e) { 

    echo $e->getMessage();
}

现在,如果您想知道表中存在多少行并且您将列“id”作为主键,那么对 DB 的查询将是:

$query = $handler->query("SELECT id FROM your_table_name");

最后,要获得与您的查询匹配的行数,如下所示:

$amountOfRows = $query->rowCount();

或者你可以写:

$query = $handler ->query("SELECT COUNT(id) FROM your_table_name");

$amountOfRows = $query->rowCount();

或者,如果您想知道“产品”表中有多少产品的价格在 10 到 20 之间,请编写以下查询:

$query = $handler ->query("SELECT id FROM products WHERE price BETWEEN 10 AND 
20");

$amountOfRows = $query->rowCount();
于 2019-02-21T18:13:41.437 回答
-2

取列()

如果想获得记录计数,则使用[effisien]

$sql   = "SELECT COUNT(*) FROM fruit WHERE calories > 100";
$res   = $conn->query($sql);
$count = $res->fetchColumn(); // ex = 2

询问()

用于检索数据和记录计数[选项]

$sql = "SELECT * FROM fruit WHERE calories > 100";
$res = $conn->query($sql);

if ( $res->rowCount() > 0) {

    foreach ( $res as $row ) {
        print "Name: {$row['NAME']} <br />";
    }

}
else {
    print "No rows matched the query.";
}

PDOStatement::rowCount

于 2020-05-14T07:39:05.043 回答
-5

使用参数 array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL),否则显示-1:

使用参数 array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL),sin ello sale -1

例子:

$res1 = $mdb2->prepare("SELECT clave FROM $tb WHERE id_usuario='$username' AND activo=1 and id_tipo_usuario='4'", array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$res1->execute();

$count=$res1->rowCount();
echo $count;
于 2016-03-23T18:32:15.650 回答