有很多相互矛盾的说法。在PHP中使用PDO获得行数的最佳方法是什么?在使用PDO之前,我只是简单地使用了mysql_num_rows。
fetchAll是我不想要的东西,因为我有时可能要处理大型数据集,所以不适合我使用。
你有什么建议吗?
有很多相互矛盾的说法。在PHP中使用PDO获得行数的最佳方法是什么?在使用PDO之前,我只是简单地使用了mysql_num_rows。
fetchAll是我不想要的东西,因为我有时可能要处理大型数据集,所以不适合我使用。
你有什么建议吗?
当前回答
因此,其他答案已经确定不应该使用rowCount()来计算SELECT语句的行数。文档甚至说:
PDOStatement::rowCount()返回受相应PDOStatement对象执行的最后一个DELETE、INSERT或UPDATE语句影响的行数。
https://web.archive.org/web/20220409162106/https://www.php.net/manual/en/pdostatement.rowcount.php
所以对于其他查询是可以的,但是对于SELECT就不太好了。大多数答案建议您进行两个查询,一个用于统计行数,另一个用于获取所需记录的子集。但是,您可以在一个请求中查询行数和您的数据子集。这有点像打高尔夫球的代码练习,但是如果请求时间有点昂贵,并且这些请求是经常发出的,那么实际上可以证明比两个请求更有效。
如果你在PostgreSQL中,你可以提供干净的JSON输出,如下所示:
WITH mytable as (VALUES(1,2,3),(4,5,6),(7,8,9),(10,11,12))
SELECT
jsonb_build_object(
'rowcount', (SELECT count(1) FROM mytable)
,'data', (
SELECT jsonb_agg(data.*)
FROM (
SELECT *
FROM mytable
WHERE column1 > 1 -- pagination offset
ORDER BY column1
LIMIT 2 -- page size
) as data
)
) jsondata
输出:
{"data": [
{
"column1": 4,
"column2": 5,
"column3": 6
},
{
"column1": 7,
"column2": 8,
"column3": 9
}
],
"rowcount": 4
}
如果你不在postgres中,这些函数将不可用,但你可以这样做:
WITH mytable as (VALUES(1,2,3),(4,5,6),(7,8,9),(10,11,12))
SELECT
(SELECT count(1) FROM mytable) as rowcount
,data.*
FROM (
SELECT *
FROM mytable as mytable(column1, column2, column3)
WHERE column1 > 1 -- pagination offset
ORDER BY column1
LIMIT 2 -- page size
) as data
但是它会返回每一行的行数,这可能有点浪费:
rowcount | column1 | column2 | column3 |
---|---|---|---|
4 | 4 | 5 | 6 |
4 | 7 | 8 | 9 |
其他回答
要在查询中使用变量,必须使用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
这篇文章是旧的,但获得行计数在php与PDO是简单的
$stmt = $db->query('SELECT * FROM table');
$row_count = $stmt->rowCount();
下面是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();
}
}
对于直接查询,我想要一个特定的行,并想知道它是否被找到,我使用类似于:
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;
}
正如经常发生的那样,这个问题让人非常困惑。人们来这里有两个不同的任务:
它们需要知道表中有多少行 它们需要知道查询是否返回了任何行
这是两个完全不同的任务,没有任何共同之处,不能用同一个函数来解决。具有讽刺意味的是,对于它们都必须使用实际的PDOStatement::rowCount()函数。
让我们看看为什么
计算表中的行数
在使用PDO之前,我只是简单地使用mysql_num_rows()。
Means you already did it wrong. Using mysql_num_rows() or rowCount() to count the number of rows in the table is a real disaster in terms of consuming the server resources. A database has to read all the rows from the disk, consume the memory on the database server, then send all this heap of data to PHP, consuming PHP process' memory as well, burdening your server with absolute no reason. Besides, selecting rows only to count them simply makes no sense. A count(*) query has to be run instead. The database will count the records out of the index, without reading the actual rows and then only one row returned.
出于这个目的,在接受的答案中建议的代码是公平的,只是它不会是一个“额外的”查询,而是要运行的唯一查询。
计算返回的行数。
第二个用例不是灾难性的,而是毫无意义的:如果您需要知道您的查询是否返回任何数据,您总是拥有数据本身!
例如,如果您只选择一行。好了,你可以使用被取的行作为标志:
$stmt->execute();
$row = $stmt->fetch();
if (!$row) { // here! as simple as that
echo 'No data found';
}
如果您需要获取很多行,那么您可以使用fetchAll()。
fetchAll()是我不想要的东西,因为我有时可能要处理大型数据集
是的,当然,对于第一个用例,它将是两倍的糟糕。但是,正如我们已经了解到的,不要只选择行来计数它们,无论是使用rowCount()还是fetchAll()。
但是如果您真的要使用所选的行,那么使用fetchAll()并没有什么错。记住,在一个web应用程序中,你不应该选择大量的行。只有在网页上实际使用的行应该被选择,因此你必须在SQL中使用LIMIT, WHERE或类似的子句。对于这样少量的数据,可以使用fetchAll()。同样,在条件中使用这个函数的结果:
$stmt->execute();
$data = $stmt->fetchAll();
if (!$data) { // again, no rowCount() is needed!
echo 'No data found';
}
当然,运行一个额外的查询只是为了告诉您的另一个查询是否返回任何行,这绝对是疯狂的,就像它在顶部的两个答案中所建议的那样。
计算大结果集中的行数
在这种需要选择大量行(例如在控制台应用程序中)的罕见情况下,您必须使用无缓冲的查询,以减少内存使用量。但这是rowCount()不可用的实际情况,因此这个函数也没有用处。
因此,这是您可能需要运行额外查询的唯一用例,以防您需要知道所选行数的接近估计值。