使用PDO进行行计数

时间:2009-05-19 15:12:31

标签: php mysql pdo

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

fetchAll是我不想要的,因为我有时可能会处理大型数据集,因此对我的使用不利。

你有什么建议吗?

23 个答案:

答案 0 :(得分:243)

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

这不是最优雅的方式,而且还需要额外的查询。

PDO有PDOStatement::rowCount(),显然 在MySql中工作。多么痛苦。

来自PDO Doc:

  

对于大多数数据库,   PDOStatement :: rowCount()没有   返回受影响的行数   一个SELECT语句。相反,使用   PDO :: query()发出SELECT   COUNT(*)语句与此相同   谓词作为您的预期SELECT   声明,然后使用   PDOStatement :: fetchColumn()到   检索将要的行数   被退回那么您的申请可以   执行正确的操作。

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

$nRows = $pdo->query('select count(*) from blah')->fetchColumn(); 
echo $nRows;

答案 1 :(得分:81)

正如我之前在an answer to a similar question中所写的那样,mysql_num_rows()工作的唯一原因是因为它在内部提取所有行以向您提供该信息,即使它看起来不像您。

所以在PDO中,你的选择是:

  1. 使用MySQL的FOUND_ROWS()功能。
  2. 使用PDO的fetchAll()函数将所有行提取到数组中,然后在其上使用count()
  3. SELECT COUNT(*)进行额外查询,如karim79建议的那样。

答案 2 :(得分:21)

  

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

首先不应该使用它

mysql_num_rows()以及PDOStatement::rowCount()表示您已选择您的数据。在这种情况下,这种功能只有两种可能的用例:

  1. 您选择的数据仅用于计算。
  2. 您想知道您的查询是否返回任何行。
  3. 前者永远不应该使用。一个人永远不应该选择行来计算它们,因为你的服务器确实可能因为返回大数据集而窒息。

    此外,仅选择行来计算它们根本没有意义。必须运行count(*)查询,只返回一行。

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

    假设,如果您只选择一行,则只需获取它,然后检查结果:

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

    如果您需要获得许多行,则可以使用fetchAll()

      

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

    请注意,在Web应用程序中,您不应该选择大量的行。只应选择将在网页上实际使用的行。为此,必须使用SQL中的LIMIT或类似子句。对于如此适量的数据,可以使用fetchAll()

    在极少数情况下,当您需要选择真正的大量行(例如在控制台应用程序中)时,为了减少使用的内存量,您必须使用unbuffered query, but in this case rowCount() won't be available anyway,因此也没用这个功能。

    因此,您可以看到,rowCount()既没有用例也没有用于替换它的额外查询,如接受的答案所示。

答案 3 :(得分: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();

这很简单,也很简单。 :)

答案 4 :(得分:18)

我最终使用了这个:

$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>";
}

答案 5 :(得分:8)

这篇文章很老但是用PDO获取行计数很简单

$stmt = $db->query('SELECT * FROM table');
$row_count = $stmt->rowCount();

答案 6 :(得分:5)

这是一篇很老的帖子,但是在寻找替代方案时感到沮丧。非常不幸的是,PDO缺乏此功能,特别是因为PHP和MySQL倾向于齐头并进。

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

  1. 水果 - &GT;香蕉
  2. 水果 - &GT;苹果
  3. 水果 - &GT;橙
  4. 如果使用fetchColumn(),你会发现返回了3个水果,但如果你现在循环结果,你只有两列,fetchColumn()的价格是第一列结果的丢失只是为了找出返回了多少行。这导致了草率编码,并且如果实施则完全错误的结果。

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

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

答案 7 :(得分:2)

回答这个问题是因为我现在已经知道了这一点并且可能会有用。

请记住,您无法两次获取结果。您必须将获取结果保存到数组中,按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
    }                       
}

答案 8 :(得分:1)

如果你只想获得行数(不是数据),即。在预准备语句中使用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)

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

答案 9 :(得分:1)

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

答案 10 :(得分:0)

要在查询中使用变量,可以bindValue()bindParam() 要在查询中使用变量,必须使用bindValue()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();

GL

答案 11 :(得分:0)

有一个简单的解决方案。如果您使用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();
}

然后,对数据库的查询将是:

$query = $handler->query("SELECT id FROM your_table WHERE ...");

最后,要计算与查询匹配的行,如下所示

$amountOfRows = $query->rowcount();

答案 12 :(得分:-1)

快速一个班轮,以获得第一个条目返回。这非常适合非常基本的查询。

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

Reference

答案 13 :(得分:-1)

我尝试使用Oracle 11.2 $count = $stmt->rowCount();,但它没有用。 我决定使用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;

答案 14 :(得分:-1)

这是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();
    }
}

答案 15 :(得分:-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;
}

答案 16 :(得分:-1)

fetchColumn()

用于想要获取记录数 [effisien]

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

query()

如果要检索数据和记录数 [选项]

,则使用
$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

答案 17 :(得分:-1)

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

$sql = $db->query("SELECT COUNT(*) FROM tablename WHERE statement='condition'");
echo $sql->fetchColumn();

答案 18 :(得分:-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语句计算的整数 写入有点长但执行速度快

编辑: 抱歉错误的帖子,但是作为一些示例显示查询与count in,我建议使用mysql结果,但如果你不使用sql中的count 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;
}

答案 19 :(得分:-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);

答案 20 :(得分:-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>

答案 21 :(得分:-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; 
}

答案 22 :(得分:-3)

使用参数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;