2024 PHP 开发者大会 日本站

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

变更日志

版本 描述
8.4.0 现在已弃用传递 mode 参数。从 PHP 8.1.0 开始,此参数无效。

示例

参见 mysqli_multi_query()

备注

注意:

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

参见

添加注释

用户贡献的注释 4 条注释

11
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);

// 一次处理第一个存储过程的一行数据
while($picksRow = $resultPicks->fetch_array(MYSQLI_ASSOC)) {
// 获取下一个存储过程的参数
$symbol = $picksRow['Symbol'];

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

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

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

// 释放第二个存储过程的结果
$resultData->free();

}

// 释放第一个存储过程的结果
$resultPicks->free();

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

#------------------------------------------
function clearStoredResults($mysqli_link){
#------------------------------------------
while($mysqli_link->next_result()){
if(
$l_result = $mysqli_link->store_result()){
$l_result->free();
}
}
}
?>
2
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 {
/* 第一个查询错误 */
}
-3
Warner
15年前
似乎在 multi_query() 中执行 SET 语句也会返回额外的记录集,这并非预期。
-5
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