Количество строк с PDO


есть много противоречивых заявлений вокруг. Каков наилучший способ подсчета строк с помощью PDO в PHP? Перед использованием PDO, я просто использовал mysql_num_rows.

fetchAll это то, что я не хочу, потому что иногда я могу иметь дело с большими наборами данных, поэтому не очень хорошо для моего использования.

есть ли у вас какие-либо предложения?

21 158

21 ответ:

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

не самый элегантный способ сделать это, плюс он включает в себя дополнительный запрос.

PDO есть PDOStatement::rowCount(), что, по-видимому, делает не работа в MySql. Какая боль.

из документа PDO:

для большинства баз данных, PDOStatement:: rowCount() не делает возвращает количество строк, затронутых инструкция Select. Вместо этого используйте PDO:: query() для выдачи SELECT COUNT (*) оператор с тем же предикаты как ваш предполагаемый выбор заявление, а затем использовать PDOStatement:: fetchColumn () to получить количество строк, которые будут быть возвращены. Затем ваше приложение может выполнить правильное действие.

EDIT: в приведенном выше примере кода используется подготовленный оператор, который во многих случаях, вероятно, не нужен для подсчета строк, поэтому:

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

как я писал ранее в ответ на аналогичный вопрос единственная причина mysql_num_rows() работал потому, что он внутренне извлекал все строки, чтобы дать вам эту информацию, даже если вам это не казалось.

так что в PDO, ваши варианты:

  1. используйте MySQL FOUND_ROWS()

Это супер поздно, но я столкнулся с проблемой и я делаю это:

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();

это действительно просто и легко. :)

перед использованием PDO я просто использовал mysql_num_rows().

вы не должен был использовать его в первую очередь.

mysql_num_rows(), а также PDOStatement::rowCount() подразумевает, что вы уже выбран ваш данных. В этом случае возможны только два варианта использования такой функции:

  1. вы выбрали свои данные только для того, чтобы получить счет.
  2. вы хотите знать, возвращается ли ваш запрос все строки.

и первый никогда не должен использоваться вообще. никогда не следует выбирать строки для их подсчета, так как ваш сервер действительно может задохнуться из-за большого возвращаемого набора данных.

кроме того, выбор строк только для их подсчета просто не имеет смысла. А count(*) запрос должен быть запущен вместо С возвращением только одной строки.

второй вариант использования менее катастрофичен, но довольно бессмыслен: в случае, если вам нужно знать, является ли ваш запрос вернул любые данные, у вас всегда есть сами данные!

скажем, если вы выбираете только одну строку, то просто извлеките ее и проверьте результат:

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

в случае, если вам нужно получить много строк, то вы можете использовать fetchAll().

fetchAll() что-то я не хочу, как я могу иметь дело с большими наборами данных

обратите внимание, что в веб-приложении вы никогда не должны выбирать огромное количество строк. Только строк быть фактически использованы на веб-странице должны быть выбраны. Для которой цели LIMIT или аналогичное предложение в SQL должны быть использованы. И для такого умеренного количества данных можно использовать fetchAll()

в таком редком случае, когда вам нужно выбрать реальное огромное количество строк (например, в консольном приложении), чтобы уменьшить объем используемой памяти, вы должны использовать unbuffered query,но в этом случае rowCount() не будет в любом случае, таким образом есть эта функция также не используется.

так что вы видите, нет никакого прецедента ни для rowCount() ни для дополнительного запроса, чтобы заменить его, как предлагается в принятом ответе.

Я в конечном итоге с помощью этого:

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

этот пост старый, но получение количества строк в php с PDO просто

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

Это старый пост, но разочаровываюсь в поисках альтернатив. Очень жаль, что PDO не хватает этой функции, тем более что PHP и MySQL, как правило, идут рука об руку.

существует неудачный недостаток в использовании fetchColumn (), поскольку вы больше не можете использовать этот результирующий набор (эффективно), поскольку fetchColumn () перемещает иглу в следующую строку. Так, например, если у вас есть результат, аналогичный

  1. Фрукты->Банан
  2. Фрукт->Яблоко
  3. Фрукты->Оранжевый

Если вы используете fetchColumn (), вы можете узнать, что есть 3 возвращенных фрукта, но если вы теперь просматриваете результат, у вас есть только два столбца, цена fetchColumn () - это потеря первого столбца результатов, чтобы узнать, сколько строк было возвращено. Это приводит к небрежному кодированию и полностью ошибочным результатам, если они реализованы.

Так что теперь, используя fetchColumn () вы должны реализовать и полностью новый вызов и запрос MySQL, чтобы получить новый рабочий результирующий набор. (надеюсь, не изменился с момента последнего запроса), я знаю, маловероятно, но это может произойти. Кроме того, накладные расходы двойных запросов на все проверки количества строк. Что для этого примера мало, но разбор 2 миллионов строк на Объединенный запрос, не приятная цена для оплаты.

Я люблю PHP и поддерживаю всех, кто участвует в его разработке, а также сообщество в целом, используя PHP на ежедневной основе, но очень надеюсь, что это будет рассмотрено в будущих версиях. Это "действительно" моя единственная жалоба на PHP PDO, который в противном случае является отличным классом.

отвечая на это, потому что я в ловушке себя с ним теперь, зная это и, возможно, это будет полезно.

имейте в виду, что вы не можете дважды принести результаты. Вы должны сохранить результат выборки в массив, получить количество строк по 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
    }                       
}

Если вы просто хотите получить количество строк (не данные) ie. используя 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)

фактически извлечение всех строк (данных) для выполнения простого подсчета является пустой тратой ресурсов. Если результирующий набор Большой ваш сервер может задохнуться на нем.

посмотрите на эту ссылку: http://php.net/manual/en/pdostatement.rowcount.php Не рекомендуется использовать rowCount () в операторах SELECT!

когда речь идет о 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'];

кредиты идут к Майку @ codeofaninja.com

вот пользовательское расширение класса PDO с вспомогательной функцией для получения количества строк, включенных в критерии "где" последнего запроса.

возможно, вам придется добавить больше "обработчиков", хотя, в зависимости от того, какие команды вы используете. Сейчас он работает только для запросов, которые используют "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();
    }
}

быстро один лайнер, чтобы получить первую запись. Это хорошо для очень простых запросов.

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

ссылка

пробовал $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;

для прямых запросов, где я хочу определенную строку, и хочу знать, если она была найдена, я использую что-то вроде:

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

функции count_x($подключение) { $запрос = " выбрать * из ТБЛ где id = '0' "; $заявление = $подключения->подготовить($запроса); $заявление->выполнить(); $total_rows = $заявление->параметр rowcount(); вернуть $total_rows; }

когда вы делаете COUNT (*) в своем операторе mysql, как в

$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 fetchAll() эффективно, если вы сохраните результат в переменной, вы не потеряете строку.

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

count($table) вернет номер строки, и вы все еще можете использовать Результат после like $row = $table[0] или через foreach

foreach($table as $row){
  print $row->id;
}

вы можете объединить лучший метод в одну строку или функцию и автоматически сгенерировать новый запрос:

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

$numRows = getRowCount($query);
$qry = "select * from tabel";
$cmd = $conn->prepare($qry);
$cmd->execute();
$cmd->rowCount()
<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>

параметр использовать array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL), еще покажут -1:

Usen parametro 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;