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, который вернула функция mysqli_connect() или функция mysqli_init().

mode

Устанавливаемая опция. Начиная с PHP 8.1, параметр ни на что не влияет. Может иметь одно из следующих значений:

Допустимые варианты
Имя Описание
MYSQLI_STORE_RESULT_COPY_DATA Копирует результаты из внутреннего буфера mysqlnd в получаемые переменные PHP. По умолчанию mysqlnd использует ссылки, предотвращая копирование и дублирование результатов в памяти. В некоторых случаях, например, если результаты содержат много небольших рядов, копирование может уменьшить общее потребление памяти, так как переменные PHP, содержащие результат, можно освобождать раньше (доступно только при использовании mysqlnd)

Возвращаемые значения

Возвращает буферизованный объект результата запроса или false в случае ошибки.

Замечание:

mysqli_store_result() возвращает false, если запрос не возвращает результирующей таблицы (например, в случае выражения INSERT). Также функция вернёт false, если данные из результирующего набора не удалось прочитать. Наличие ошибки можно проверить функцией mysqli_error(), которая в этом случае вернёт непустую строку; mysqli_errno() вернёт ненулевое значение; и mysqli_field_count() также вернёт ненулевое значение. Также возможной причиной возврата false после успешного вызова mysqli_query() может быть слишком большой результирующий набор (не хватает памяти для его размещения). Если функция mysqli_field_count() возвращает ненулевое значение, значит запрос вернул непустой результирующий набор.

Ошибки

Если уведомления об ошибках mysqli включены (MYSQLI_REPORT_ERROR) и запрошенная операция не удалась, выдаётся предупреждение. Если, кроме того, установлен режим MYSQLI_REPORT_STRICT, вместо этого будет выброшено исключение mysqli_sql_exception.

Примеры

Смотрите mysqli_multi_query().

Примечания

Замечание:

Даже несмотря на хорошую практику очищать память, занятую результатами запросов, посредством функции mysqli_free_result(), если mysqli_store_result() передаёт большой результирующий набор, это может стать проблемой.

Смотрите также

  • mysqli_real_query() - Выполнение SQL запроса
  • mysqli_use_result() - Готовит результирующий набор на сервере к использованию

add a note add a note

User Contributed Notes 5 notes

up
9
mitchind
14 years ago
After reading through original notes and example above as well as wading through the documentation, I finally got a loop to work with two stored procedures.

Using the results of the first one as a parameter for the second one. Easier to do this way than a huge modified sequence of Inner Join queries.

Hope this helps others...

<?php
// Connect to server and database
$mysqli        = new mysqli("$dbServer", "$dbUser", "$dbPass", "$dbName");

// Open First Stored Procedure using MYSQLI_STORE_RESULT to retain for looping
$resultPicks = $mysqli->query("CALL $proc ($searchDate, $maxRSI, $incRSI, $minMACD, $minVol, $minTrades, $minClose, $maxClose)", MYSQLI_STORE_RESULT);

// process one row at a time from first SP
while($picksRow = $resultPicks->fetch_array(MYSQLI_ASSOC)) {
   
// Get Parameter for next SP
   
$symbol     = $picksRow['Symbol'];

   
// Free stored results
   
clearStoredResults($mysqli);

   
// Execute second SP using value from first as a parameter (MYSQLI_USE_RESULT and free result right away)
   
$resultData    = $mysqli->query("CALL prcGetLastMACDDatesBelowZero('$symbol', $searchDate)", MYSQLI_USE_RESULT);
   
$dataRow    = $resultData->fetch_array(MYSQLI_ASSOC);

   
// Dump result from both related queries
   
echo "<p>$symbol ... Num Dates: " . $dataRow['NumDates'];

   
// Free results from second SP
   
$resultData->free();

}

// Free results from first SP
$resultPicks->free();

// close connections
$mysqli->close();

#------------------------------------------
function clearStoredResults($mysqli_link){
#------------------------------------------
   
while($mysqli_link->next_result()){
      if(
$l_result = $mysqli_link->store_result()){
             
$l_result->free();
      }
    }
}
?>
up
0
filippo at ecoms dot it
6 years ago
Code to handling errors:

if ($mysqli->multi_query($query)) {
    $result = $mysqli->store_result();
    if ($mysqli->errno == 0) {
   
        /* First result set or FALSE (if the query didn't return a result set) is stored in $result */

        while ($mysqli->more_results()) {
            if ($mysqli->next_result()) {
                $result = $mysqli->store_result();
                if ($mysqli->errno == 0) {
                    /* The result set or FALSE (see above) is stored in $result */
                }
                else {
                    /* Result set read error */
                    break;
                }
            }
            else {
                /* Error in the query */
            }
        }
    }
    else {
        /* First result set read error */
    }
}
else {
    /* Error in the first query */
}
up
-3
Warner
15 years ago
It also seems, that executing a SET statement in multi_query() returns an extra recordset too, which one would not expect.
up
-3
lau at goldenweb dot com dot au
17 years ago
Beware when using stored procedures:
If you connect to the database and then call dbproc A followed by a call to db proc B and then close the connection to the db, the second procedure call will not work.

It looks like there is a bug in MYSQL or mysqli that returns an extra recordset than you would expect. It then doesn't let you call another stored procedure until you finish processing all the recordsets from the first stored procedure call.

The solution is to simply loop through the additional recordsets between calls to db procs. Here is a function that I call between db proc calls:

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

?>
up
-5
Tex Morgan
11 years ago
There's a simpler way to clear out database stored procedure problems:

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(); // <----------- recursive call is your friend
            }
        }
    }
.......
}
To Top