PDO和存储过程的无缓冲查询错误

时间:2012-11-13 16:42:15

标签: php mysql sql stored-procedures pdo

我正在考虑一个项目,我正在做的一部分是用对存储过程的调用替换内联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 ; 

正如我上面提到的,当我尝试实例化添加到数组的新请求时,会出现问题。这似乎导致我看到的光标问题,因为我使用fetchAll()应该不解决问题?是否有处理此类情景的最佳做法?任何建议将非常感谢。非常感谢!

1 个答案:

答案 0 :(得分:4)

完成陈述后,您应该拨打closeCursor(),如下所示:

$stmt->closeCursor();

通过关闭游标,可以使连接可​​用于新请求。有关详细信息,请参阅 PDOStatement::closeCursor 上的PHP文档。