У меня есть следующий код:
$dbh = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $dbh->prepare("SELECT 1");
$stmt->execute();
$result = $stmt->fetch();
$stmt->execute();
$result = $stmt->fetch();
$stmt = $dbh->prepare("SELECT 1");
$stmt->execute();
$result = $stmt->fetch();
Однако по какой-то причине я получаю следующую ошибку при выполнении подготовленного оператора второй:
Неустранимая ошибка: исключить исключение "PDOException" с сообщением 'SQLSTATE [HY000]: общая ошибка: 2014 Не удается выполнить запросы во время другие небуферизованные запросы активны. Рассмотрите возможность использования PDOStatement:: fetchAll(). Кроме того, если ваш код только когда-либо для запуска с mysql, вы можете включить буферизацию запроса, установив атрибут PDO:: MYSQL_ATTR_USE_BUFFERED_QUERY. '
Я знаю, что означает эта ошибка и как ее исправить (либо делать unset($stmt);
, либо $stmt->closeCursor();
), поэтому я не ищу решения, как заставить его работать. Из того, что я понимаю, это обычно вызвано тем, что fetch
вместо fetchAll
и не извлекает все результаты. Однако в этом случае есть только один результат, и он извлекается. Кроме того, если я выполняю только первый подготовленный оператор один раз, ошибка не возникает. Это происходит только тогда, когда первый оператор выполняется дважды. Это также происходит, когда PDO::ATTR_EMULATE_PREPARES
false
.
Итак, мой вопрос в том, что вызывает вышеупомянутую ошибку в этом случае? Кажется, он не отличается от любого другого запроса, который я когда-либо выполнял.
Я тестировал это на двух серверах Ubuntu 13.10, Debian и CentOS, и все они вызывают ту же ошибку, используя пакеты по умолчанию.
Edit:
Чтобы ответить на комментарий Райана Винсента, я полный mysqli noob, но я считаю, что то, что у меня ниже, примерно эквивалентно приведенному выше примеру. Пожалуйста, поправьте меня, если я ошибаюсь. Однако он не вызывает ошибок, поэтому он выглядит как ошибка PDO:
$mysqli = new mysqli($host, $user, $pass, $dbname);
if ($mysqli->connect_errno) {
die("Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error);
}
if (!($stmt = $mysqli->prepare("SELECT 1"))) {
die("Prepare 1 failed: (" . $mysqli->errno . ") " . $mysqli->error);
}
if (!$stmt->execute()) {
die("Execute 1 failed: (" . $stmt->errno . ") " . $stmt->error);
}
$stmt->store_result();
$stmt->bind_result($col1);
$stmt->fetch();
if (!$stmt->execute()) {
die("Execute 2 failed: (" . $stmt->errno . ") " . $stmt->error);
}
$stmt->store_result();
$stmt->bind_result($col1);
$stmt->fetch();
if (!($stmt = $mysqli->prepare("SELECT 1"))) {
// The following line is what fails in PDO
die("Prepare 2 failed: (" . $mysqli->errno . ") " . $mysqli->error);
}
if (!$stmt->execute()) {
die("Execute 3 failed: (" . $stmt->errno . ") " . $stmt->error);
}
$stmt->store_result();
$stmt->bind_result($col1);
$stmt->fetch();