该错误源于客户端未按mysql协议处理完上一个查询的结果集便发送新命令。php需用mysqli_store_result()或mysqli_use_result()配合fetch和free;python需显式调用fetchall()等并用nextset()处理多结果集;c api须循环调用mysql_next_result()清理所有结果集。

这个错误不是 MySQL 服务端出问题,而是客户端违反了协议:上一个查询的结果集没处理完,就急着发新命令——连接状态“卡住”了,MySQL 直接拒绝后续操作。
PHP mysqli 忘记消费 SELECT 结果集
最常见于执行 mysqli_query() 得到结果后,没调 mysqli_store_result() 或 mysqli_fetch_all(),就直接执行下一条 mysqli_query()(哪怕是 INSERT 或 CLOSE)。
- 小结果集:执行完
mysqli_query()后立刻调mysqli_store_result(),再mysqli_free_result() - 大结果集:用
mysqli_use_result()+ 循环mysqli_fetch_row(),最后必须mysqli_free_result() - 哪怕只查
COUNT(*)也得取一次结果,否则状态残留;mysqli_store_result()+mysqli_free_result()是最稳妥的兜底写法
Python mysql-connector / PyMySQL 多语句未清理结果集
cursor.execute() 不会自动帮你清空前序结果。尤其在循环中反复执行 SELECT,但没调 cursor.fetchall() 或 cursor.close(),下一轮就崩。
- 每次
execute()后,若可能返回结果,必须显式消费:cursor.fetchall()、cursor.fetchone()或cursor.fetchmany(n) - 执行存储过程或含多个
SELECT的语句时,要用cursor.nextset()跳转并检查是否还有结果集,直到返回None - 使用
mysql-connector-python创建存储过程?别写DELIMITER,也别把CREATE PROCEDURE和其他语句拼在一条字符串里——拆成单条execute(),每条后加cursor.nextset()检查
C API 中漏掉 mysql_next_result() 循环
调用 mysql_real_query() 执行存储过程或含多个结果集的语句后,仅用 mysql_store_result() 只能拿到第一个结果集。剩余结果集不清理,下次查询必报错。
- 执行后先
mysql_store_result()处理首个结果集 - 然后用
while (mysql_next_result(conn) == 0)循环,每次循环内再调mysql_store_result()+mysql_free_result() - 注意:
mysql_next_result()返回 0 表示还有结果集,-1 表示无更多结果,1 表示出错——别只判非零就跳出
真正容易被忽略的是多结果集场景:哪怕某次 SELECT 返回空行,或存储过程中间有隐式 SELECT、SHOW,只要服务端发了结果集包,客户端就必须收完。协议不讲情面,也不猜你意图。











