MySQL存储过程调用报2014命令不同步及PHP内存溢出问题求助
问题解决说明
核心前提
mysql_use_result()、mysql_free_result()、mysql_store_result()均为MySQL客户端侧(如PHP的MySQL相关扩展)提供的API,无法在MySQL存储过程内部使用。你遇到的报错本质是PHP端调用返回多结果集的存储过程时,结果集处理逻辑错误导致的。
报错原因说明
- 2014
Commands out of sync报错:存储过程返回多个结果集时,客户端必须按顺序读取完全部返回的结果集、释放资源后,才能执行下一条SQL命令,否则MySQL会直接抛出该错误。phpMyAdmin默认没有适配多结果集存储过程的处理逻辑,因此直接执行CALL语句就会报错。 - 内存耗尽+执行耗时过长:如果PHP端默认使用
mysql_store_result()模式处理结果集,会将所有结果(尤其是你存储过程中第二个查询是SELECT * FROM deprates,如果该表数据量很大)全部一次性加载到PHP进程内存中,就会触发内存超限报错,同时大量数据的IO传输也会导致执行时间大幅拉长。
正确处理方案(PHP端)
目前PHP官方早已废弃旧的mysql扩展,推荐使用mysqli扩展处理数据库操作,正确的多结果集存储过程调用示例如下:
<?php // 初始化数据库连接 $mysqli = new mysqli('数据库主机地址', '账号', '密码', '库名'); if ($mysqli->connect_error) { die('数据库连接失败: ' . $mysqli->connect_error); } $inputRefNo = '2021/0000012'; // 转义参数避免SQL注入 $safeRefNo = $mysqli->real_escape_string($inputRefNo); // 调用存储过程 if ($mysqli->multi_query("CALL GetAllParts('{$safeRefNo}')")) { $resultSeq = 1; do { // 获取当前结果集:use_result对应旧API的mysql_use_result,逐行拉取不占用过多内存,适合大结果集 // 如果结果集很小可以替换为store_result,对应旧API的mysql_store_result,读取速度更快 if ($currentResult = $mysqli->use_result()) { echo "第 {$resultSeq} 个结果集:\n"; while ($row = $currentResult->fetch_assoc()) { // 此处编写你的业务处理逻辑 var_dump($row); } // 释放当前结果集资源,对应旧API的mysql_free_result $currentResult->free(); $resultSeq++; } // 切换到下一个结果集 } while ($mysqli->more_results() && $mysqli->next_result()); } // 关闭数据库连接 $mysqli->close(); ?>
额外优化建议
- 存储过程中
SELECT * FROM deprates如果无特殊全表查询需求,建议增加必要的过滤条件,减少数据传输量,能大幅降低执行耗时和内存占用。 - 如果仍在使用PHP5.6及更早版本的旧
mysql扩展,处理逻辑和上述示例一致,依次用mysql_use_result()/mysql_store_result()取结果、mysql_free_result()释放资源、mysql_next_result()切换下一个结果集即可,但强烈建议升级到mysqli或PDO扩展,旧扩展存在严重安全风险且不再维护。
内容的提问来源于stack exchange,提问作者Kumar Kush
相关产品推荐
相关产品推荐

