mysqli::store_result

mysqli_store_result

(PHP 5, PHP 7, PHP 8)

mysqli::store_result -- mysqli_store_result从最后一次查询中传输结果集

描述

面向对象风格

public mysqli::store_result(int $mode = 0): mysqli_result|false

过程化风格

mysqli_store_result(mysqli $mysql, int $mode = 0): mysqli_result|false

将由 mysql 参数表示的数据库连接上的最后一次查询的结果集传输到要与 mysqli_data_seek() 函数一起使用的结果集。

参数

mysql

仅限过程化风格:由 mysqli_connect()mysqli_init() 返回的 mysqli 对象

mode

您要设置的选项。从 PHP 8.1 开始,此参数无效。它可以是以下值之一

有效选项
名称 描述
MYSQLI_STORE_RESULT_COPY_DATA 将结果从内部 mysqlnd 缓冲区复制到 PHP 变量中。默认情况下,mysqlnd 将使用引用逻辑来避免复制和重复内存中保存的结果。对于某些结果集,例如包含许多小行的结果集,复制方法可以减少总体内存使用,因为保存结果的 PHP 变量可以更早地释放(仅适用于 mysqlnd)

返回值

返回一个缓冲结果对象,如果发生错误则返回 false

注意:

mysqli_store_result() 在查询未返回结果集(例如,查询是 INSERT 语句)的情况下返回 false。如果读取结果集失败,此函数也会返回 false。您可以通过检查 mysqli_error() 是否不返回空字符串,mysqli_errno() 是否返回非零值,或者 mysqli_field_count() 是否返回非零值来检查是否出现了错误。另外,在成功调用 mysqli_query() 后,此函数返回 false 的另一个可能原因是结果集太大(无法分配内存)。如果 mysqli_field_count() 返回非零值,则语句应该已经生成了一个非空的结果集。

错误/异常

如果启用了 mysqli 错误报告(MYSQLI_REPORT_ERROR)并且请求的操作失败,则会生成警告。此外,如果将模式设置为 MYSQLI_REPORT_STRICT,则会抛出 mysqli_sql_exception 而不是警告。

示例

参见 mysqli_multi_query().

注释

注意:

虽然始终建议使用 mysqli_free_result() 函数释放查询结果使用的内存,但在使用 mysqli_store_result() 传输大型结果集时,这一点尤其重要。

参见

添加注释

用户贡献注释 5 个注释

mitchind
14 年前
在阅读了上面的原始注释和示例以及浏览了文档之后,我终于让一个循环与两个存储过程一起工作。

将第一个存储过程的结果用作第二个存储过程的参数。这样做比一大堆修改后的内部联接查询更容易。

希望这能帮助其他人…

<?php
// 连接到服务器和数据库
$mysqli = new mysqli("$dbServer", "$dbUser", "$dbPass", "$dbName");

// 使用 MYSQLI_STORE_RESULT 打开第一个存储过程以保留以循环
$resultPicks = $mysqli->query("CALL $proc ($searchDate, $maxRSI, $incRSI, $minMACD, $minVol, $minTrades, $minClose, $maxClose)", MYSQLI_STORE_RESULT);

// 处理第一个 SP 的每一行
while($picksRow = $resultPicks->fetch_array(MYSQLI_ASSOC)) {
// 获取下一个 SP 的参数
$symbol = $picksRow['Symbol'];

// 释放存储的结果
clearStoredResults($mysqli);

// 使用第一个 SP 的值为参数执行第二个 SP(MYSQLI_USE_RESULT 并立即释放结果)
$resultData = $mysqli->query("CALL prcGetLastMACDDatesBelowZero('$symbol', $searchDate)", MYSQLI_USE_RESULT);
$dataRow = $resultData->fetch_array(MYSQLI_ASSOC);

// 转储两个相关查询的结果
echo "<p>$symbol ... 日期数量: " . $dataRow['NumDates'];

// 释放第二个 SP 的结果
$resultData->free();

}

// 释放第一个 SP 的结果
$resultPicks->free();

// 关闭连接
$mysqli->close();

#------------------------------------------
function clearStoredResults($mysqli_link){
#------------------------------------------
while($mysqli_link->next_result()){
if(
$l_result = $mysqli_link->store_result()){
$l_result->free();
}
}
}
?>
filippo at ecoms dot it
6 年前
处理错误的代码

if ($mysqli->multi_query($query)) {
$result = $mysqli->store_result();
if ($mysqli->errno == 0) {

/* 第一个结果集或 FALSE(如果查询没有返回结果集)存储在 $result 中 */

while ($mysqli->more_results()) {
if ($mysqli->next_result()) {
$result = $mysqli->store_result();
if ($mysqli->errno == 0) {
/* 结果集或 FALSE(见上文)存储在 $result 中 */
}
else {
/* 读取结果集出错 */
break;
}
}
else {
/* 查询出错 */
}
}
}
else {
/* 读取第一个结果集出错 */
}
}
else {
/* 第一个查询出错 */
}
Warner
15 年前
似乎在 multi_query() 中执行 SET 语句也会返回一个额外的记录集,这是意料之外的。
Tex Morgan
11 年前
有一个更简单的清除数据库存储过程问题的方法

class MySQLiQuery {
protected $_resultSet;
protected $databaseConnection;
....

protected function free(){
$this->_resultSet->free();
$this->_resultSet=null;
}

protected function checkMoreResults(){
if($this->databaseConnection->more_results()){
return true;
} else {
return false;
}
}

protected function clearResults(){
if($this->checkMoreResults()){
if($this->databaseConnection->next_result()){
if($this->_resultSet=$this->databaseConnection->store_result()){
$this->free();
}
$this->clearResults(); // <----------- 递归调用是你的朋友
}
}
}
.......
}
lau at goldenweb dot com dot au
17 年前
使用存储过程时要注意
如果你连接到数据库,然后调用 dbproc A,接着调用 db proc B,最后关闭数据库连接,则第二个过程调用将无法工作。

看起来 MYSQL 或 mysqli 中存在一个错误,它返回了比预期多一个的记录集。然后它不允许你调用另一个存储过程,直到你完成对第一个存储过程调用中所有记录集的处理。

解决方案是在调用 db proc 之间简单地循环遍历额外的记录集。以下是我在调用 db proc 之间调用的函数

<?php
#--------------------------------
function ClearRecordsets($p_Result){
#--------------------------------
$p_Result->free();
while(
$this->Mysqli->next_result()){
if(
$l_result = $this->Mysqli->store_result()){
$l_result->free();
}
}
}

?>
To Top