PHP 7.2.0 Release Candidate 4 Released

mysqli::store_result

mysqli_store_result

(PHP 5, PHP 7)

mysqli::store_result -- mysqli_store_result直近のクエリから結果セットを転送する

説明

オブジェクト指向型

mysqli_result mysqli::store_result ([ int $option ] )

手続き型

mysqli_result mysqli_store_result ( mysqli $link [, int $option ] )

mysqli_data_seek() で使用される、 link で表されたデータベース接続の直近のクエリ から結果セットを転送します。

パラメータ

link

手続き型のみ: mysqli_connect() あるいは mysqli_init() が返すリンク ID。

option

指定したいオプション。以下のいずれかの値を指定します。

有効なオプション
名前 説明
MYSQLI_STORE_RESULT_COPY_DATA 結果を、内部の mysqlnd バッファーから PHP の変数にコピーします。 デフォルトでは、mysqlnd は参照を利用しており、メモリ内の結果をコピーしたり複製したりしないようにしています。 ある種の結果セット (短めの行を大量に保持する結果セットなど) の場合は、 コピーしたほうが、全体的なメモリ使用量を抑えることができます。 結果を保持する PHP の変数のほうが、解放されるのが早いからです。 これは mysqlnd でのみ利用可能で、PHP 5.6.0 以降で使えます。

返り値

バッファに格納した結果オブジェクトを返します。エラー時には FALSE を返します。

注意:

mysqli_store_result() は、クエリが結果セットを 返さなかった場合(例えば、クエリが INSERT 文であった場合)に FALSE を返します。また、結果セットの読み込みに失敗した場合にも FALSE を返します。エラーが発生したかどうかを調べるには、 mysqli_error() が空文字列以外を返す・ mysqli_errno() がゼロ以外の値を返す・あるいは mysqli_field_count() がゼロ以外の値を返す のいずれかを確認します。それ以外にこの関数が FALSE を返す理由としては mysqli_query() のコールに成功して返された 結果セットが大きすぎる(メモリに割り当てられない)場合がありえます。 もし mysqli_field_count() がゼロ以外の値を 返した場合、文は空でない結果セットを生成しています。

注意

注意:

クエリ結果が使用するメモリを mysqli_free_result() 関数で開放するのは、どんな場合でも大切です。しかし、大きい結果セットを mysqli_store_result() で転送した際は、特にこれが 重要となります。

mysqli_multi_query() を参照ください。

参考

add a note add a note

User Contributed Notes 4 notes

up
9
mitchind
7 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
-1
lau at goldenweb dot com dot au
10 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
-2
Warner
8 years ago
It also seems, that executing a SET statement in multi_query() returns an extra recordset too, which one would not expect.
up
-2
Tex Morgan
4 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