PDO Небуферизованные запросы

Я пытаюсь войти в детали PDO. Поэтому я закодировал это:

$cn = getConnection(); // get table sequence $comando = "call p_generate_seq('bitacora')"; $id = getValue($cn, $comando); //$comando = 'INSERT INTO dsa_bitacora (id, estado, fch_creacion) VALUES (?, ?, ?)'; $comando = 'INSERT INTO dsa_bitacora (id, estado, fch_creacion) VALUES (:id, :estado, :fch_creacion)'; $parametros = array ( ':id'=> (int)$id, ':estado'=>1, ':fch_creacion'=>date('Ymd H:i:s') ); execWithParameters($cn, $comando, $parametros); 

моя функция getValue работает нормально, и я получаю следующую последовательность для таблицы. Но когда я попадаю в execWithParameters, я получаю это исключение:

PDOException: SQLSTATE [HY000]: общая ошибка: 2014 Невозможно выполнить запросы, в то время как другие небуферизованные запросы активны. Рассмотрим использование PDOStatement :: fetchAll (). Кроме того, если ваш код будет работать только с mysql, вы можете включить буферизацию запросов, установив атрибут PDO :: MYSQL_ATTR_USE_BUFFERED_QUERY. в D: \ Servidor \ xampp_1_7_1 \ htdocs \ bitacora \ func_db.php в строке 77

Я попытался изменить атрибуты соединения, но он не работает.

Это мои основные функции db:

 function getConnection() { try { $cn = new PDO("mysql:host=$host;dbname=$bd", $usuario, $clave, array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, )); $cn->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); return $cn; } catch (PDOException $e) { print "Error!: " . $e->getMessage() . "<br/>"; die(); } } function getValue($cn, $comando) { $resul = $cn->query($comando); if (!$resul) return null; while($res = $resul->fetch()) { $retorno = $res[0][0]; break; } return $retorno; } function execWithParameters($cn, $comando, $parametros) { $q = $cn->prepare($comando); $q->execute($parametros); if ($q->errorInfo() != null) { $e = $q->errorInfo(); echo $e[0].':'.$e[1].':'.$e[2]; } } 

Кто-нибудь, кто может пролить свет на это? Оплаченный Пожалуйста, не предлагайте делать autonumeric id, потому что я портирую с другой системы.

Проблема в том, что mysql допускает только один выдающийся курсор в данный момент времени. Используя метод fetch () и не потребляя все ожидающие данные, вы оставляете курсор открытым.

Рекомендуемый подход состоит в том, чтобы использовать все данные, используя метод fetchAll (). Альтернативой является использование метода closeCursor ().

Если вы измените эту функцию, я думаю, вы будете счастливее:

 <?php function getValue($cn, $comando) { $resul = $cn->query($comando); if (!$resul) return null; foreach ($resul->fetchAll() as $res) { $retorno = $res[0]; break; } return $retorno; } ?> 

Я не думаю, что PDOStatement :: closeCursor () будет работать, если вы не выполняете запрос, который возвращает данные (например, UPDATE, INSERT и т. Д.).

Лучшим решением является просто отключить () ваш объект PDOStatement после вызова PDOStatement :: execute ():

 $stmt = $pdo->prepare('UPDATE users SET active = 1'); $stmt->execute(); unset($stmt); 

Проблема, похоже, в том, что — я не слишком хорошо знаком с PDO — после того, как ваш getValue-вызов возвращается, запрос по-прежнему привязан к соединению (вы только запрашиваете первое значение, но соединение возвращает несколько, или ожидает этого).

Возможно, getValue можно зафиксировать, добавив

 $resul->closeCursor(); 

до возвращения.

В противном случае, если запросы getValue всегда возвращают одно (или несколько достаточно) значение, кажется, что использование fetchAll будет предпочтительным.

Я просто трачу 15 минут на поиск по всему Интернету и просматриваю как минимум 5 различных вопросов, связанных с Stackoverflow, некоторые из которых утверждали, что моя ошибка, по-видимому, возникла из-за неправильной версии PHP, неправильной версии библиотеки MySQL или любого другого волшебного материала с черным ящиком …

Я изменил весь свой код на использование «fetchAll», и я даже вызвал closeCursor () и unset () в объекте запроса после каждого запроса. Я честно отчаялся! Я также попробовал флаг MYSQL_ATTR_USE_BUFFERED_QUERY, но он не сработал.

НАКОНЕЦ Я выбросил все из окна и посмотрел на ошибку PHP, и отслеживал строку кода, где это произошло.

 SELECT AVG((original_bytes-new_bytes)/original_bytes) as saving FROM (SELECT original_bytes, new_bytes FROM jobs ORDER BY id DESC LIMIT 100) AS t1 

В любом случае проблема возникла из-за того, что мои оригинальные_байты и new_bytes были как беззнаковыми, так и в том случае, если у меня когда-либо была работа, где new_bytes, где на самом деле LARGER, чем original_bytes, тогда у меня была бы неприятная ошибка MySQL за пределами диапазона. И это произошло случайно, после того, как я немного поработал над моим сервисом по мини-настройке.

Почему, черт возьми, я получил эту странную ошибку MySQL вместо того, чтобы просто дать мне простую ошибку, это вне меня! Фактически он появился в SQLBuddy (легкий PHPMyAdmin), когда я запускал необработанный запрос. У меня были исключения PDO, поэтому он должен был просто дать мне ошибку MySQL.

Ничего, нижняя строка:

Если вы когда-нибудь получите эту ошибку, обязательно проверьте, что ваш необработанный MySQL на самом деле правильный и STILL работает !!!

У моего друга была такая же проблема с сборкой xampp 1.7.1. После замены xampp / php / * на сборку 5.2.9-2 php.net и копирование всех необходимых файлов в xampp / apache / bin, он работал нормально.

Если вы используете XAMPP 1.7.1, вам просто нужно перейти на 1.7.2.