mysqli_affected_rows 返回上一次insert、update、delete或replace实际影响的行数;对select等只读语句固定返回-1,非错误;update值未变时返回0;事务中不回滚其值。

mysqli_affected_rows 返回什么值?
mysqli_affected_rows 不是“执行成功就返回 1”,它只反映上一次 INSERT、UPDATE、DELETE 或 REPLACE 实际改动的行数。对 SELECT、SHOW、DESCRIBE 这类只读语句,它固定返回 -1 —— 这不是报错,是设计如此。
常见误判:看到 -1 就以为 SQL 执行失败,其实可能只是你刚查完数据又顺手调了 mysqli_affected_rows,它没东西可报。
- INSERT INTO ... VALUES (...) → 成功插入 1 行,返回 1;插入多行,返回实际行数
- UPDATE ... WHERE id = 123 → 即使条件匹配,但新旧值完全一样(比如 SET status='done' 但原来就是 'done'),MySQL 默认不计为“影响”,返回 0(除非开启
sql_mode=STRICT_TRANS_TABLES并配合其他设置) - DELETE FROM t WHERE 1=0 → 匹配 0 行,返回 0;不是报错,也不是 null
为什么 mysqli_affected_rows 有时返回 -1?
根本原因:它只对“修改类”语句有效。一旦你混用查询和更新,或在 mysqli_query 后没立刻调用它,就容易踩坑。
典型场景:
- 先
mysqli_query($conn, "SELECT * FROM users"),再mysqli_affected_rows($conn)→ 必然 -1 - 用
mysqli_multi_query执行多个语句,但没用mysqli_next_result切换结果集,直接调mysqli_affected_rows→ 返回的是第一个语句的影响数,后续的全丢 - 连接被复用,前一个请求是 SELECT,当前请求是 UPDATE,但忘了检查上一步是否真执行了写操作 → 值来自上一个 SELECT,还是 -1
验证方法:在每次 INSERT/UPDATE/DELETE 后**立即**调用 mysqli_affected_rows,且确保前面没有其他非修改语句干扰。
与 mysqli_num_rows 的区别在哪?
mysqli_num_rows 数的是 SELECT 结果集有多少行,mysqli_affected_rows 数的是写操作实际变更了几行 —— 它们压根不在一个维度,不能互相替代,也不能混着判断逻辑。
采用HttpClient向服务器端action请求数据,当然调用服务器端方法获取数据并不止这一种。WebService也可以为我们提供所需数据,那么什么是webService呢?,它是一种基于SAOP协议的远程调用标准,通过webservice可以将不同操作系统平台,不同语言,不同技术整合到一起。 实现Android与服务器端数据交互,我们在PC机器java客户端中,需要一些库,比如XFire,Axis2,CXF等等来支持访问WebService,但是这些库并不适合我们资源有限的android手机客户端,
错误用法示例:
if (mysqli_affected_rows($conn) > 0) {
// 以为这是“查到了数据”,其实这是“改了数据”
}正确对应关系:
- 想确认 INSERT 是否成功插入 → 看
mysqli_affected_rows是否 ≥ 1 - 想确认 UPDATE 是否真的改了内容(而非白跑一趟)→ 看
mysqli_affected_rows是否 > 0(注意:0 表示匹配但未变更) - 想确认 SELECT 返回了几条记录 → 必须用
mysqli_num_rows,且要传入mysqli_query返回的结果资源,不是连接资源
事务中怎么安全用 mysqli_affected_rows?
在 START TRANSACTION 后,每个语句仍会独立影响 mysqli_affected_rows 的返回值,但它**不感知事务最终是否提交**。也就是说,即使你最后 ROLLBACK,之前各步的 mysqli_affected_rows 值也不会回滚或清零。
所以别靠它判断事务是否生效。真正该做的:
- 每条写语句后立刻捕获
mysqli_affected_rows,存到变量里(如 $inserted = mysqli_affected_rows($conn);) - 等整个事务
COMMIT成功后再用这些变量做业务判断 - 如果
ROLLBACK,那些变量的值依然存在,但已失效 —— 你需要重置逻辑,而不是重读mysqli_affected_rows
最容易被忽略的一点:PDO 的 rowCount() 在预处理后行为更一致,而原生 mysqli 的这个函数对无符号整数、大数值、甚至某些 MySQL 版本的 INSERT ... ON DUPLICATE KEY UPDATE 返回值都有微妙差异,生产环境建议加类型断言或范围校验。









