0

私はプロジェクトをリファクタリングしています。私が行っていることの一部は、インライン SQL をストアド プロシージャの呼び出しに置き換えることです。問題が発生しました。PHP バージョン 5.3.5 と MySQL バージョン 5.0.7 を使用しています。

プロジェクトにはメンバーがいて、メンバーはリクエストを持つことができます。特定のメンバーに対するすべてのリクエストを取得し、それらを Request オブジェクトの配列として返したいと考えています。

すべてのリクエスト ID を返すストアド プロシージャを呼び出す静的メソッドを作成しました。これを使用して、新しい Request オブジェクトをインスタンス化します。問題は、バッファリングされていないクエリに関するエラーが発生することです。エラーは次のとおりです。

General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute  

エラーメッセージが示唆するように実行し、fetchAllを使用しましたが、まだこの問題が発生しています。関連する PHP の簡易バージョンを次に示します。

class Request
{
    public function __construct($request_id)
    {
        //as you can see this is still inline 
        $db = Database::get_instance();
        $sql = "SELECT field1,field2,field3 FROM requests WHERE request_id = ?";
        $stmt = $db->prepare($sql);
        $stmt->execute(array($request_id));
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        if(!empty($row))
        {
            //populate properties
            foreach($row as $key=>$value)
            {
                $this->$key = $value; 
            }   
        }

    }

    public static function get_requests_by_member_id($member_id)
    {
        //array to hold results
        $requests = array();
        //this is just a PDO object
        $db = Database::get_instance();
        $sql = "CALL get_requests_by_member_id(?)";
        $stmt = $db->prepare($sql);
        /bind the param 
        $stmt->bindParam(1,$member_id,PDO::PARAM_INT,10);
        $stmt->execute();
        //iterate through adding new Request objects to the array       
        foreach($stmt->fetchAll(PDO::FETCH_ASSOC) as $row)
        {
            //here is where the problem occurs
            $requests[] = new self($row['request_id']);
        }

        return $requests;   

    }

}

そして、ストアド プロシージャの簡易版:

delimiter $$

CREATE PROCEDURE get_requests_by_member_id(member_id_in INT)
BEGIN
    SELECT request_id 
    FROM requests 

    WHERE cr.member_id = member_id_in;
END$$
delimiter ; 

上で述べたように、新しい Request をインスタンス化して配列に追加しようとすると、問題が発生します。これは、私が見ているカーソルの問題を引き起こしているように見えますが、問題を解決しないはずの fetchAll() を使用したためですか? この種のシナリオを処理するためのベスト プラクティスはありますか? アドバイスをいただければ幸いです。どうもありがとう!

4

1 に答える 1

4

ステートメントを使い終わったら、次closeCursor()のようにを呼び出す必要があります。

$stmt->closeCursor();

カーソルを閉じると、接続が新しいリクエストに使用できるようになります。詳細については、 PDOStatement::closeCursorに関する PHP ドキュメントを参照してください。

于 2012-11-13T17:33:41.543 に答える