Количество строк с PDO
Существует много противоречивых утверждений. Каков наилучший способ подсчета строк с использованием PDO в PHP? Перед использованием PDO я просто использовал mysql_num_rows . fetchAll — это то, чего я не хочу, потому что иногда я могу иметь дело с большими наборами данных, поэтому не полезно для моего использования. Есть ли у вас какие-либо предложения?
22 ответа
$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;
это будет означать выполнение дополнительного запроса к базе данных. Я предполагаю, что он уже выполнил запрос на выборку и теперь хочет знать, сколько строк было возвращено.
После небольшого приближения все начинает выглядеть так, будто выбор счетчика (*) может быть самым красивым подходом! странный
Используя этот подход, fetchColumn() возвращает строку «1234» . ваш EDIT имеет echo count($nRows); — count() является функцией массива: P. Я также рекомендовал бы приведение типа приведения результата из fetchColumn() к целому числу. $count = (int) $stmt->fetchColumn()
@ karim79 Неподготовленный подход оператора возвращает 1 только вместо фактического числа строк. Подготовленное заявление работает отлично. В чем может быть проблема?
@SilentAssassin Я также столкнулся с той же проблемой. Комментарий Cobbys, чуть выше вашего комментария, запрещает использовать count($nRows) как он предназначен для массивов. Я предполагаю, что функция видит результат как массив с результатом (значением или нулем) в любом случае и всегда возвращает 1.
И прямо сейчас квест. Что использовать и что быстрее rowCount () или fetchColumn () или запрос mysql> SELECT SQL_CALC_FOUND_ROWS * FROM . ; mysql> SET @rows = FOUND_ROWS ();
Это и выбор всех данных только для подсчета не лучший результат для производительности в любом случае.
Согласно php PDOStatement :: rowCount () возвращает количество строк, затронутых оператором DELETE, INSERT или UPDATE. Так что он не будет работать с select согласно инструкции PHP.
Как я уже писал ранее в ответе на аналогичный вопрос, единственная причина, по которой работал mysql_num_rows() , — это то, что она внутренне извлекала все строки, чтобы предоставить вам эту информацию, даже если это не похоже на вас.
- Используйте функцию MySQL FOUND_ROWS() .
- Используйте функцию PDO fetchAll() для извлечения всех строк в массив, а затем используйте count() на ней.
- Сделайте дополнительный запрос к SELECT COUNT(*) , как предположил karim79.
Спасибо за то, что вы рассказали мне больше о mysql_num_rows (), похоже, это может быть важным узким местом, которое я давал себе. Еще раз спасибо.
Это очень поздно, но я столкнулся с проблемой, и я это делаю:
function countAll($table)< $dbh = dbConnect(); $sql = "select * from `$table`"; $stmt = $dbh->prepare($sql); try < $stmt->execute();> catch(PDOException $e)getMessage();> return $stmt->rowCount();
Это действительно просто и легко.:)
Выбор всех данных только для их подсчета противоречит самым основным правилам взаимодействия с базой данных.
Возможно, вы хотите иметь индикатор выполнения для всех возвращаемых значений, поэтому вам нужно знать количество строк заранее.
Перед использованием PDO я просто использовал mysql_num_rows() .
Вы не должны были использовать его.
mysql_num_rows() , а также PDOStatement::rowCount() подразумевает, что вы уже выбрали свои данные. В этом случае для такой функции возможны только два возможных варианта использования:
- Вы выбрали свои данные, чтобы получить счет.
- Вы хотите знать, возвращал ли ваш запрос любые строки.
И первый никогда не должен использоваться вообще. Никогда не следует выбирать строки для их подсчета, так как ваш сервер действительно может задохнуться из-за возврата большого набора данных.
Кроме того, выбор строк только для их подсчета просто не имеет смысла. Вместо этого должен выполняться запрос count(*) , с возвратом только одной строки.
Второй вариант использования менее пагубный, но не бессмысленный: в случае, если вам нужно знать, вернул ли ваш запрос какие-либо данные, у вас всегда есть данные!
Скажем, если вы выбираете только одну строку, просто выберите ее и проверьте результат:
$stmt->execute(); $row = $stmt->fetch(); if ($row) < // here! as simple as that >
Если вам нужно получить много строк, вы можете использовать fetchAll() .
fetchAll() — это то, чего я не хочу, поскольку иногда я могу иметь дело с большими наборами данных
Обратите внимание, что в веб-приложении вы никогда не должны выбирать огромное количество строк. Должны быть выбраны только строки, которые будут фактически использоваться на веб-странице. Для чего необходимо использовать LIMIT или аналогичное предложение в SQL. И для такого умеренного объема данных все в порядке использовать fetchAll()
В таком редком случае, когда вам нужно выбрать реальное огромное количество строк (например, в консольном приложении), чтобы уменьшить объем используемой памяти, вы должны использовать небуферизованный запрос, , но в этом случае rowCount() будет недоступен в любом случае, поэтому для этой функции также не нужно использовать.
Итак, вы видите, нет никакого случая ни для rowCount() , ни для дополнительного запроса, чтобы его заменить, как это предлагается в принятом ответе.
это полезно, если API должен распечатать итоговые результаты поискового запроса. он вернет вам только 10 или 15 строк, но также должен сказать, что всего 284 результата.
@andufo Это не так. Пожалуйста, помните: разработчик никогда не должен делать это таким образом. Поисковый запрос никогда не должен возвращать все 284 строки. 15 должны быть возвращены, чтобы показать, и одна строка из отдельного запроса, чтобы сказать, что 284 были найдены.
Это очень хороший момент — сначала не интуитивно понятный, но действительный. Большинство людей забывают, что два простых SQL-запроса намного быстрее, чем чуть больший. Чтобы оправдать любые подсчеты, вам нужно иметь очень медленный запрос, который нельзя оптимизировать и который, вероятно, даст мало результатов. Спасибо что подметил это!
@Your Здравый смысл: просто будьте уверены: не будет ли fetchAll () плохой идеей, если набор результатов очень большой? Не лучше ли использовать fetch () для последовательного получения данных.
В итоге я использовал это:
$result = $db->query($query)->fetchAll(); if (count($result) > 0) < foreach ($result as $row) < echo $row['blah'] . '
'; > > else < echo "Nothing matched your query.
"; >
Это сообщение старое, но получение числа строк в php с PDO прост
$stmt = $db->query('SELECT * FROM table'); $row_count = $stmt->rowCount();
Это старое сообщение, но разочарование ищет альтернативы. К сожалению, PDO испытывает недостаток в этой функции, особенно потому, что PHP и MySQL имеют тенденцию идти рука об руку.
Есть неудачный недостаток в использовании fetchColumn(), поскольку вы больше не можете использовать этот набор результатов (эффективно), поскольку fetchColumn() перемещает иглу в следующую строку. Например, если у вас есть результат, похожий на
Если вы используете fetchColumn(), вы можете узнать, что есть три возвращенных плода, но если теперь вы пройдете через результат, у вас будет только два столбца. Цена fetchColumn() — это потеря первого столбца результатов просто чтобы узнать, сколько строк было возвращено. Это приводит к небрежному кодированию, и при условии, что они полностью исключены.
Итак, теперь, используя fetchColumn(), вы должны реализовать и полностью новый вызов и запрос MySQL, чтобы получить новый рабочий набор результатов. (который, надеюсь, не изменился со времени вашего последнего запроса), я знаю, маловероятно, но это может произойти. Кроме того, накладные расходы на двойные запросы при проверке количества строк. Что для этого примера мало, но разбор 2 миллионов строк в объединенном запросе, а не приятная цена для оплаты.
Я люблю PHP и поддерживаю всех, кто участвует в его разработке, а также сообщество в целом, используя PHP на ежедневной основе, но на самом деле надеюсь, что это будет рассмотрено в будущих выпусках. Это «действительно» моя единственная жалоба с PHP PDO, которая в противном случае является отличным классом.
Rowcount() to get number of rows affected by Query
WE can use rowCount() to know number of rows or records affected by the latest sql statement involving any Delete , update , insert command. This function is to be used immediately after the sql execute command. This function works similar to mysql_affected_rows function
rowcount() to get number of records affected by Query involving any Delete , update & insert command
WE will learn some examples on how to use this in our pdo example table. Download the dump file of pdo_admin table at the end of the tutorial.
$count=$dbo->prepare("update pdo_admin set status='T' "); //$count=$dbo->prepare("delete from pdo_admin where status='F'");
$count->execute(); $no=$count->rowCount(); echo " No of records = ".$no;
Output will show number of records updated or deleted from the table ( based on which line is executed )
$count=$dbo->prepare("delete from pdo_admin where status='F'"); $count->execute(); $no=$count->rowCount(); echo " No of records = ".$no;
The output will show us number of records deleted from the pdo_admin table.
Same way you can do for insert command.
rowcount with SELECT Command
Usually rowCount() works with delete, update and insert commands but rowCount does not give reliable data when used with SELECT query in MySQL, so it is better to use Count command to get total number of records. Here is an example.
$nume = $dbo->query("select count(id) from pdo_admin")->fetchColumn(); echo "
Number of records : ". $nume;
Here id field we used as this is an auto incremented field. If such field is not there then we can use all the records like this.
$nume = $dbo->query("select count(*) from pdo_admin")->fetchColumn();
rowCount and truncate
If you are deleting all records of a table by using Truncate command then rowCount won’t able to return you number of records deleted.