Небуферизованная ошибка запроса с PDO и хранимыми процедурами
Я пересматриваю проект, и часть того, что я делаю, заменяет встроенный SQL вызовами хранимых процедур. Я столкнулся с проблемой. Я использую PHP версии 5.3.5 и MySQL версии 5.0.7
У проекта есть участники, у участников могут быть запросы. Я хочу получить все запросы для конкретного члена и вернуть их в виде массива объектов запроса.
Я создал статический метод, который вызывает сохраненный процесс, который возвращает все идентификаторы запросов, которые я, в свою очередь, использую для создания экземпляров новых объектов запросов. Проблема в том, что я получаю ошибку относительно небуферизованных запросов, вот ошибка:
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 ответ
Когда вы закончите с заявлением, вы должны позвонить closeCursor()
, вот так:
$stmt->closeCursor();
Закрыв курсор, вы делаете соединение доступным для новых запросов. Подробности смотрите в документации PHP по PDOStatement::closeCursor.