2

私のデータベースには、いくつかのストアド プロシージャがあります。

そのうちの 1 つを呼び出したいのですが、この手順で得られた結果に従って、2 つ目のものを呼び出すかどうかを天気で判断します。

isUserValid()私が使用した方法でわかるように$result->free_results()

それでも、他のプロシージャを呼び出すと、次のようになります。Commands out of sync; you can't run this command now

これは、db 関数への呼び出しです。

    /**
     * Run a new query on the db.
     * this will open an close the connection to the db
     * @param $query string the query to run
     * @param $verifyAccessToken boolean true if user validation is needed before query is executed, false otherwise
     * @return bool|mysqli_result the result of the query if any or true or false in a non query
     * @throws Exception on connection and query errors
     */
    private function queryDb($query,$verifyAccessToken)
    {
       // if ($this->test)
//            echo $query . "<br>";
        //create a new mysqli connection
        $mysqli = new mysqli($this->DB_HOST, $this->DB_USER, $this->DB_PASS, $this->DB_NAME);
        //set the charset for the connection
        if (!$mysqli->set_charset("utf8"))
        {
            $mysqli->close();
            throw new Exception ("Error setting UTF 8 DB connection");
        }
        //check if the connection was ok
        if (mysqli_connect_errno())
        {
            $mysqli->close();
            throw new Exception("Error connecting DB");
        }

        //if verification is needed - verify access token
       if ($verifyAccessToken && !$this->isUserValid($mysqli))
       {
          $mysqli->close();
          throw new Exception(ACCESS_TOKEN_INCORRECT);
       }

        //get results
        $result = $mysqli->query($query);
        //check if there were now error in query. if so - throw an exception
        if (!$result)
        {
            $mysqlError = $mysqli->error . __LINE__;
            //close the connection
            $mysqli->close();
            throw new Exception ("mySQL Error: " . $mysqlError);
        }
        //fetch the results into an array
        $rows = $result->fetch_all(MYSQLI_BOTH);
        //close the connection
        $result->close();
        $result->free();
        $mysqli->close();
        //return the results if any
        return $rows;
    }

    /**
     * Check if user is valid
     * @param $mysqli mysqli connection to db
     * @return true if user is valid, false otherwise
     */
    function isUserValid($mysqli)
    {
        //Check if there is a saved access token. if not - throw an exception
        if (is_null($this->user) || $this->user->getPicoAccessToken() == null)
          throw new Exception(ACCESS_TOKEN_INCORRECT);
        //get user details
        $facebookId = $this->user->getFacebookId();
        $picoAccessToken = $this->user->getPicoAccessToken();
        //create verification query
        $verificationQuery = "Call isUserValid('$facebookId','$picoAccessToken')";
        //execute query
        $result = $mysqli->query($verificationQuery);

        //if query had error - throw exception
        if (!$result)
        {
         $mysqlError = $mysqli->error . __LINE__;
         //close the connection
         $mysqli->close();
         throw new Exception ("mySQL Error: " . $mysqlError);
        }
        $rows = $result->fetch_all(MYSQLI_ASSOC);
        $rows = $rows[0];
        $result->free_result();
        //return user valid status
        return isset($rows["isUserValid"]) && $rows["isUserValid"] == 1;
    }
4

3 に答える 3

9

すべてのストアド プロシージャは、少なくとも2 つの結果を返します

  • 1 つ (または複数) の実際の結果
  • これ以上結果がないことをクライアントに伝えるための 1 つの空の結果。

mysqli_more_results()/を使用mysqli_next_result()してそれらをきれいにする必要があります。

プロシージャが 1 つの結果のみを返す場合、または余分な結果が必要ないだけで最初の結果が必要な場合は、次のコード スニペットを使用して結果キューをクリーンアップできます。

while($mysqli->more_results())
{
    $mysqli->next_result();
    if($res = $mysqli->store_result())
    {
        $res->free(); 
    }
}
于 2013-09-29T12:10:04.730 に答える
-1

現在受け入れられている回答はそのままでは機能しnext_result()ません。最初の結果の前に呼び出すべきではないと思います。

これはうまくいく例です:

if (!$mysqli->multi_query("CALL p()")) {
    echo "CALL failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

do {
    if ($res = $mysqli->store_result()) {
        printf("---\n");
        var_dump($res->fetch_all());
        $res->free();
    } else {
        if ($mysqli->errno) {
            echo "Store failed: (" . $mysqli->errno . ") " . $mysqli->error;
        }
    }
} while ($mysqli->more_results() && $mysqli->next_result());

PHP マニュアルhttp://php.net/manual/en/mysqli.quickstart.stored-procedures.phpから

于 2015-09-29T06:48:23.383 に答える
-3

データベースを再接続する$this->db->reconnect(); // likes in codeigniter

于 2015-02-02T06:18:36.857 に答える