百科狗-知识改变命运!
--

PDOStatement::rowCount() - PDOStatement类

乐乐11个月前 (11-21)阅读数 20#技术干货
文章标签语句

PDOStatement::rowCount()

(PHP 5 >= 5.1.0, PHP 7, PECL pdo >= 0.1.0)

返回受上一个 SQL 语句影响的行数

说明

PDOStatement::rowCount(void): int

PDOStatement::rowCount()返回上一个由对应的PDOStatement对象执行DELETE、 INSERT、或 UPDATE 语句受影响的行数。

如果上一条由相关PDOStatement执行的 SQL 语句是一条 SELECT 语句,有些数据可能返回由此语句返回的行数。但这种方式不能保证对所有数据有效,且对于可移植的应用不应依赖于此方式。

返回值

返回行数。

范例

返回删除的行数

PDOStatement::rowCount()返回受 DELETE、INSERT、或 UPDATE 语句影响的行数。

以上例程会输出:

Return number of rows that were deleted:
Deleted 9 rows.

PDOStatement::rowCount() - PDOStatement类

计算由一个 SELECT 语句返回的行数

对于大多数数据库,PDOStatement::rowCount()不能返回受一条 SELECT 语句影响的行数。替代的方法是,使用PDO::query()来发出一条和原打算中的SELECT语句有相同条件表达式的 SELECT COUNT(*)语句,然后用PDOStatement::fetchColumn()来取得返回的行数。这样应用程序才能正确执行。

以上例程会输出:

apple
banana
orange
pear

参见

  • PDOStatement::columnCount() 返回结果集中的列数
  • PDOStatement::fetchColumn() 从结果集中的下一行返回单独的一列。
  • PDO::query() 执行 SQL 语句,以 PDOStatement 对象形式返回结果集
When updating a Mysql table with identical values nothing's really affected so rowCount will return 0. As Mr. Perl below noted this is not always preferred behaviour and you can change it yourself since PHP 5.3.
Just create your PDO object with 

and rowCount() will tell you how many rows your update-query actually found/matched.
Great, while using MySQL5, the only way to get the number of rows after doing a PDO SELECT query is to either execute a separate SELECT COUNT(*) query (or to do count($stmt->fetchAll()), which seems like a ridiculous waste of overhead and programming time.
Another gripe I have about PDO is its inability to get the value of output parameters from stored procedures in some DBMSs, such as SQL Server.
I'm not so sure I'm diggin' PDO yet.
Note that an INSERT ... ON DUPLICATE KEY UPDATE statement is not an INSERT statement, rowCount won't return the number or rows inserted or updated for such a statement. For MySQL, it will return 1 if the row is inserted, and 2 if it is updated, but that may not apply to other databases.
To display information only when the query is not empty, I do something like this: 
It'd better to use SQL_CALC_FOUND_ROWS, if you only use MySQL. It has many advantages as you could retrieve only part of result set (via LIMIT) but still get the total row count.
code: 
In some drivers rowCount() only works when using the prepare() with PDO::CURSOR_SCROLL
So, you can modify PDO class:

Now let's test (i using php 5.2.9-2):

My results:
-------------------
PDO_MSSQL
rowCount() Standart: 0
rowCount() New: 0
MSSQL throw PDO_ODBC
rowCount() Standart: -1
rowCount() New: 53
MS SQL driver 2.0
rowCount() Standart: -1
rowCount() New: 53
-------------------
With myPDO class you can use prepared queries like: 
MySQL does not seem to return anything in rowCount for a select statement, but you can easily and efficiently get the row count as follows:
class db extends PDO {
 public function last_row_count() {
  return $this->query("SELECT FOUND_ROWS()")->fetchColumn();
 }
}
$myDb = new db('mysql:host=myhost;dbname=mydb', 'login', 'password' );
Then, after running your query:
if ( $myDb->last_row_count() == 0 ) {
 echo "Do something!";
 }
every good work
If you use "INSERT INTO ... ON DUPLICATE KEY UPDATE" syntax, mysql_affected_rows() will return you 2 if the UPDATE was made (just as it does with the "REPLACE INTO" syntax) and 1 if the INSERT was.
So if you use one SQL request to insert several rows at a time, and some are inserted, some are just updated, you won't get the real count..
Please note another interesting behavior with PostgreSQL.
If you try to use rowCount() after a statement has been prepared using the PDO::ATTR_CURSOR set to PDO::CURSOR_SCROLL you will always get zero (0).
That's because PG doesn't have any way to tell how many rows are in the cursor until it did iterate through all rows.

Will return "0", whereas the same statement without the CURSOR_SCROLL attribute, will correctly return 1.
Please see this bug report https://bugs.php.net/bug.php?id=77855 for details.
This documentation should be updated shortly to reflect that issue.
Note: 
=====
On Mysql SELECT statement with Buffered queries, rowCount will return the correct count of the items in the result set.
BUT if your query is unbuffered, than it will return 0. No matter if all the rows are retrieved from the result set or not (while in mysqli this behaviour is different - you will still get the number of items in the result set with unbuffered queries, but only when you retrieve all the rows from the set).
Example:
========
$conn = new PDO("mysql:host=127.0.0.1;dbname=db", 'root', 'root');
// use unbuffered query
$conn->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$stmt = $conn->query("select * from towns");
echo $stmt->rowCount(); // will always return 0
As of SQLite 3.x, the SQLite API itself changed and now all queries are implemented using "statements". Because of this, there is no way for PDO to know the rowCount of a SELECT result because the SQLite API itself doesn't offer this ability.
As a workaround, I created my own rowCount() function - it's a bit of a hack and hasn't been fully tested yet (I don't know how it will work when using JOINs in SELECTs, etc...), but at least alleviates the necessity for SELECT COUNT(*)'s everywhere in your code.
I would have preferred if it were possible to overload the rowCount() function from PDOStatement, but I don't think it's possible (or I don't know how to do it). There's also potential room for a bit more security ensuring that $queryString is wiped clean after other query()s so that you don't get a bad result, etc...
The actual code should be posted in the above/below post (max post limits, argh!). If others wish to extend/perfect this method, please keep me posted with an email as to what you've done.
We're having problem with these PDOStatement::fetchColumn() and PDOStatement::rowCount(). I don't know if we have alike case to others or this is just a problem in our coding. In local, the rowCount() is not giving the correct number of rows but it is working fine when uploaded to our hosting site.. while the fetchColumn() is the reverse. The fetchColumn() is working fine in local but not anymore when uploaded. I don't know what is really going on with that but I think rowCount() is the best and the others are optional to use.
Well, I woundn't do as suggested querying twice the database to get the count and then get the data I want. It would be simpler and would give better performance to query once and retrieve both, record count and the data itself 
Yet another workaround to return the row count inside only ONE select (see limitations below!):
$sth = $dbh->prepare("SELECT *,count(*) AS howmany FROM users WHERE email=:email and password=:pass"); #var placeholders
$sth->execute(array(':email'=>$email, ':pass'=>$pass)); #var binding
$row = $sth->fetch(); #get one row (it'll always be one and only one!!!)
if ($row['howmany'] == 1){ #we have a match and only one! cool!
  echo $row['email'], $row['name'], $row['phone'], ... ;
} elseif ($row['howmany']>1) { #more than one row returned
  #one programmer should be fired 'cause he's not checking for
  #for existing emails, before creating a new user
  ... 
  # treat this exception somehow or simply skip this branch, 
  # if you're sure it won't happen in your table
} else { #no match in the table ($row['howmany'] == 0)
  echo "Email/pass didn't match the ones in the database!";
}
Advantages: 
- only one select statement is executed, no two steps needed!
- it checks if one row exists in the table or not, according to the WHERE clause.
- it returns all (or only a selection of) fields for that one row, if exists.
Disadvantages:
- it doesn't return row fields reliable if more than one row found. If more than one row responds to the SELECT query, the query returns still only one row and you don't know which one exactly .
Maybe using a SORT BY, would make it a bit more predictible (as in: "if more than one users found, return the last user added in the table") but it's more a matter of good design of the program that fills in the table initially.
Uses: 
- It is perfect for checking if a user/pass pair is present in a users table and to return the other fields of the user (like name, phone, whatever) if user was found.
My rowCount() workaround & how it's used:

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)