标签:php mysql sql pdo stored-procedures
我正在尝试使用PDO调用存储过程,但在尝试对结果进行获取时遇到以下错误.
警告:数据包乱序.预计1收到16.数据包大小= 163
我的存储过程使用两个游标,我在从临时表中选择之前关闭它.我怀疑这可能是问题,因为我可以直接在MySQL中调用我的SP并且可以看到结果.在迁移到php_pdo_mysql.dll之前使用php_mysql扩展时,我也没遇到过这个SP的问题.
我还可以使用PDO在PHP中调用包含INPUT参数的其他更简单的存储过程,并且可以在没有任何错误的情况下获取结果.
以下是返回错误的代码:
$db = new PDO('mysql:host='.__DB_HOST__.';dbname='.__DB_NAME__.';charset=utf8', __DB_USER__, __DB_PASS__);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
/* DOES NOT WORK */
$queryResult = $db->prepare("CALL GetResults(:siteId,null)");
$siteId = 19;
$queryResult->bindValue(':siteId', $siteId, PDO::PARAM_INT);
$queryResult->execute();
$result = $queryResult->fetchAll(PDO::FETCH_ASSOC); // returns packets out of order warning
print_r($result);
我在Try / Catch块中有这个代码,没有抛出任何异常.实际上,PHP在浏览器中将其显示为警告.
我的存储过程签名如下所示:
CREATE DEFINER=`root`@`localhost`
PROCEDURE `GetResults`(IN siteIdParam INT(11), IN siteSearchText VARCHAR(45))
我也不确定问题是否将null作为一个参数传递.有时第一个参数传递null,有时它是第二个.但无论它总是直接在MySQL服务器上运行.
我尝试了bindParam和bindValue,结果相同.我也可以发布我的SP但它可能有点矫枉过正.
有没有办法打开PDO扩展的其他日志记录?
任何想法或建议?如果您需要更多信息,请告诉我.
注意:我使用的是PHP v5.5.4和MySQL v5.6.14.
解决方法:
在花了很多时间试图隔离我的代码部分来解决这个问题后,我注意到在将ATTR_EMULATE_PREPARES标志设置为true后错误消失了.
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
这告诉PDO模拟准备好的语句,而不是MySQL本地模拟.根据我一直在阅读的内容,如果您使用的是最新版本的MySQL和PHP,通常建议关闭此标志(默认情况下为true).您可以在此SO article中找到有关该信息的更多信息.
我相信这是MySQL的一个错误(我遇到了5.6.17版本的问题).关于这个特定问题的讨论不多,所以希望这可以节省其他时间的故障排除.这个问题也在this MySQL bug page讨论过,但是在我的情况下,发布的解决方案对我没有帮助.
标签:php,mysql,sql,pdo,stored-procedures 来源: https://codeday.me/bug/20190713/1454505.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。