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

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

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

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

 $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 (*) с теми же предикатами, что и ваш запрошенный оператор SELECT, а затем используйте PDOStatement :: fetchColumn (), чтобы получить количество строк, которое будет возвращено. Затем ваше приложение может выполнить правильное действие.

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

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

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

Таким образом, в PDO ваши варианты:

  1. Используйте FOUND_ROWS() MySQL.
  2. Используйте fetchAll() PDO для извлечения всех строк в массив, а затем используйте count() .
  3. Сделайте дополнительный запрос к SELECT COUNT(*) , как предположил karim79.

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

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

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

Таким образом, вы видите, нет никакого 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>"; } 

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

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

  1. Фруктовое> Banana
  2. Фруктовое> Apple,
  3. Фруктовое> Оранжевый

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

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

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

Это сообщение старое, но количество строк в php с PDO прост

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

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

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

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

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

Посмотрите на эту ссылку: 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']; 

кредиты идут на Mike @ codeofaninja.com

Вот заказное расширение класса 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(); } } 

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

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

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

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

когда вы делаете 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, немного длинным для записи, но быстро выполняемым

Измените: извините за неправильную запись, но, поскольку в каком-то примере показан запрос с подсчетом, я предлагал использовать результат 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; } 
 <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) параметров array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL) , иначе покажите -1:

Usen parametro array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL) , продажа греческой ello -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;