Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 调用MySQL存储过程时出现数据包无序错误_Php_Mysql_Sql_Stored Procedures_Pdo - Fatal编程技术网

Php 调用MySQL存储过程时出现数据包无序错误

Php 调用MySQL存储过程时出现数据包无序错误,php,mysql,sql,stored-procedures,pdo,Php,Mysql,Sql,Stored Procedures,Pdo,我试图使用PDO调用一个存储的proc,但在尝试获取结果时出现以下错误 警告:数据包顺序错误。预期1人收到16份。数据包大小=163 我的存储过程使用两个游标,在从临时表中选择之前关闭它们。我怀疑这可能是问题所在,因为我可以在MySQL中直接调用我的SP,并且可以看到结果。在迁移到php_pdo_mysql.dll之前,使用php_mysql扩展时,我也从未遇到过这个SP的问题。 我还可以使用PDO在PHP中调用包含输入参数的其他更简单的存储过程,并且可以获取结果而不会出现任何错误 以下是返回错

我试图使用PDO调用一个存储的proc,但在尝试获取结果时出现以下错误

警告:数据包顺序错误。预期1人收到16份。数据包大小=163

我的存储过程使用两个游标,在从临时表中选择之前关闭它们。我怀疑这可能是问题所在,因为我可以在MySQL中直接调用我的SP,并且可以看到结果。在迁移到php_pdo_mysql.dll之前,使用php_mysql扩展时,我也从未遇到过这个SP的问题。 我还可以使用PDO在PHP中调用包含输入参数的其他更简单的存储过程,并且可以获取结果而不会出现任何错误

以下是返回错误的代码:

$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))
$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); // works fine
print_r($result); 

// Call a second stored procedure
$secondCall = $db->prepare("CALL GetOtherResults()");
$secondCall->execute();
$secondResult = $secondCall->fetchAll(PDO::FETCH_ASSOC); // returns packets out of order
print_r($secondResult);
我也不确定问题是否在于将null作为参数之一传递。有时第一个参数传递null,有时是第二个。但无论如何,它总是直接在MySQL服务器上工作

我尝试了bindParam和bindValue,结果相同。我也可以发布我的SP,但这可能有点过头了

有没有办法从PDO扩展打开其他日志记录

有什么想法或建议吗?如果你需要更多的信息,请告诉我


注意:我使用的是PHP v5.5.4和MySQL v5.6.14。

在花了很多时间试图隔离部分代码以解决此问题后,我注意到在将ATTR\u EMULATE\u PREPARES标志设置为true后,错误消失了

$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
这告诉PDO模拟准备好的语句,而不是通过MySQL本机模拟。从我所读到的内容来看,如果您使用的是最新版本的MySQL和PHP,通常建议您关闭此标志(默认情况下为true)。你可以在这里找到更多的信息


我确信这是MySQL的一个bug(我在5.6.17版本之前就遇到了这个问题)。关于这个问题没有太多的讨论,所以希望这可以为其他人节省数小时的故障排除时间。上也讨论了这个问题,但发布的解决方案对我的情况没有帮助。

@http203我在使用WAMP server和mysql 5.6.17时遇到了同样的问题

$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
修复了这个问题,但我也建议增加mysql.ini中的查询限制

max_allowed_packet = 1MB //Default


为了防止将来出现问题,对于任何有相关问题的人,请阅读这篇参考文章

我在尝试更改PDO::ATTR_EMULATE_属性时遇到了相同的问题

当我尝试在同一PDO连接上调用第二条准备好的语句时,我可以可靠地重现您描述的内容。大概是这样的:

CREATE DEFINER=`root`@`localhost` 
PROCEDURE `GetResults`(IN siteIdParam INT(11), IN siteSearchText VARCHAR(45))
$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); // works fine
print_r($result); 

// Call a second stored procedure
$secondCall = $db->prepare("CALL GetOtherResults()");
$secondCall->execute();
$secondResult = $secondCall->fetchAll(PDO::FETCH_ASSOC); // returns packets out of order
print_r($secondResult);
我知道您的示例只显示了一个调用,但要触发此错误,存储的proc调用不必位于同一个文件中,只需共享同一个PDO连接即可。我希望下面的建议仍然有用

执行存储过程时,MySQL驱动程序返回两个行集。本机驱动程序要求您在重新使用连接之前处理两者。你需要,即使你不在乎里面有什么,也要在准备和打第二个电话之前。像这样:

...
$queryResult->execute();
$result = $queryResult->fetchAll(PDO::FETCH_ASSOC);
$queryResult->nextRowSet();
$queryResult->closeCursor();

// Now you can prepare your second statement
...

如果你忘了打这两个额外的电话,PDO的模拟准备会更宽容

对于我来说,将
PDO::ATTR_PERSISTENT
设置为
false
解决了这个问题


问题在升级mysql之后开始出现。不确定实际问题是什么:-/

我的存储过程中有游标。我通过一次获取所有记录,然后遍历来解决这个问题。我再也没有这个“通知”了

$sqlQuery = $conn->prepare('CALL myStoredProcedure(?,?)');
$sqlQuery->bind_param('ss', $param1, $param2);
$sqlQuery->execute();
$resultSet = $sqlQuery->get_result();
$result = $resultSet->fetch_all();
$len = sizeof($result);

for($i=0; $i < $len; $i++){
  // Fetching data and processing it
}
$sqlQuery=$conn->prepare('callmystoredprocesdure(?,));
$sqlQuery->bind_param('ss',$param1,$param2);
$sqlQuery->execute();
$resultSet=$sqlQuery->get_result();
$result=$resultSet->fetch_all();
$len=sizeof($result);
对于($i=0;$i<$len;$i++){
//获取数据并对其进行处理
}

在我的情况下,我需要关闭数据库连接

我的错误如下所示:

CREATE DEFINER=`root`@`localhost` 
PROCEDURE `GetResults`(IN siteIdParam INT(11), IN siteSearchText VARCHAR(45))
$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); // works fine
print_r($result); 

// Call a second stored procedure
$secondCall = $db->prepare("CALL GetOtherResults()");
$secondCall->execute();
$secondResult = $secondCall->fetchAll(PDO::FETCH_ASSOC); // returns packets out of order
print_r($secondResult);
致命错误:未捕获PDO异常:数据包顺序错误。 预期0收到1。数据包大小=23英寸 html\www\website\core\Database.php:41堆栈 跟踪:

这是你的电话号码


这可能会有帮助:@Barmar我看到了,并尝试了各种组合,但我不确定如何将mysqli发布的解决方案转换为PDO…在laravel中有什么想法吗?在哪里设置这个东西?在PDO对象上调用setAttribute函数。例如:$db=新的PDO(…)$db->setAttribute(PDO::ATTR\u EMULATE\u PREPARES,true);