Il mio server esegue CentOS 6.4 con MySQL 5.1.69 installato usando yum con reposos di CentOS e PHP 5.4.16 installato usando yum con i repos di ius. Edit3 Aggiornato alla versione MySQL Server: 5.5.31 Distribuito da Progetto comunità IUS e l'errore esiste ancora. Quindi cambia libreria in mysqlnd e sembra eliminare l'errore. Tuttavia, con questo avanti e indietro, è necessario sapere perché questo errore si manifesta solo a volte.Cause di errore MySQL 2014 Impossibile eseguire query mentre sono attive altre query non bufferizzate
Quando si utilizzano prodotti DOP e creazione dell'oggetto PDO utilizzando PDO::ATTR_EMULATE_PREPARES=>false
, a volte ottengo il seguente errore:
Table Name - zipcodes
Error in query:
SELECT id FROM cities WHERE name=? AND states_id=?
SQLSTATE[HY000]: 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.
File Name: /var/www/initial_install/build_database.php
Line: 547
Time of Error: Tuesday July 2, 2013, 5:52:48 PDT
linea 547 è l'ultima linea di:
$stmt_check_county->execute(array($data[5],$data[4]));
if(!$county_id=$stmt_check_county->fetchColumn())
{
$stmt_counties->execute(array($data[5]));
$county_id=db::db()->lastInsertId();
}
//$stmt_check_county->closeCursor(); //This will fix the error
$stmt_check_city->execute(array($data[3],$data[4]));
Ho avuto un problema simile diversi anni fa, ma ho aggiornato da PHP 5.1 a PHP 5.3 (e probabilmente anche MySQL è stato aggiornato), e il problema è scomparso magicamente, e ora lo ho con PHP 5.5.
Perché si manifesta solo quando PDO::ATTR_EMULATE_PREPARES=>false
e con la sola versione alternativa di PHP?
Ho anche trovato che closeCursor()
correggerà anche l'errore. Questo dovrebbe sempre essere eseguito dopo ogni query SELECT
in cui non è utilizzato fetchAll()
? Notare che l'errore si verifica ancora anche se la query è qualcosa come SELECT COUNT(col2)
che restituisce solo un valore.
Modifica A proposito, questo è il modo in cui creo la mia connessione. Ho solo recentemente aggiunto MYSQL_ATTR_USE_BUFFERED_QUERY=>true
, tuttavia, non cura l'errore. Inoltre, è possibile utilizzare il seguente script per creare l'errore.
function sql_error($e,$sql=NULL){return('<h1>Error in query:</h1><p>'.$sql.'</p><p>'.$e->getMessage().'</p><p>File Name: '.$e->getFile().' Line: '.$e->getLine().'</p>');}
class db {
private static $instance = NULL;
private function __construct() {} //Make private
private function __clone(){} //Make private
public static function db() //Get instance of DB
{
if (!self::$instance)
{
//try{self::$instance = new PDO("mysql:host=localhost;dbname=myDB;charset=utf8",'myUsername','myPassword',array(PDO::ATTR_EMULATE_PREPARES=>false,PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,PDO::ATTR_DEFAULT_FETCH_MODE=>PDO::FETCH_ASSOC));}
try{self::$instance = new PDO("mysql:host=localhost;dbname=myDB;charset=utf8",'myUsername','myPassword',array(PDO::ATTR_EMULATE_PREPARES=>false,PDO::MYSQL_ATTR_USE_BUFFERED_QUERY=>true,PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,PDO::ATTR_DEFAULT_FETCH_MODE=>PDO::FETCH_ASSOC));}
//try{self::$instance = new PDO("mysql:host=localhost;dbname=myDB;charset=utf8",'myUsername','myPassword',array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,PDO::ATTR_DEFAULT_FETCH_MODE=>PDO::FETCH_ASSOC));}
catch(PDOException $e){echo(sql_error($e));}
}
return self::$instance;
}
}
$row=array(
'zipcodes_id'=>'55555',
'cities_id'=>123
);
$data=array($row,$row,$row,$row);
$sql = 'CREATE TEMPORARY TABLE temp1(temp_id INT UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (temp_id))';
db::db()->exec($sql);
$sql='SELECT COUNT(*) AS valid FROM cities_has_zipcodes WHERE cities_id=? AND zipcodes_id=?';
$stmt1 = db::db()->prepare($sql);
$sql ='SELECT temp_id FROM temp1';
$stmt2 = db::db()->prepare($sql);
foreach($data AS $row)
{
try
{
$stmt1->execute(array($row['zipcodes_id'],$row['cities_id']));
$rs1 = $stmt1->fetch(PDO::FETCH_ASSOC);
//$stmt1->closeCursor();
syslog(LOG_INFO,'$rs1: '.print_r($rs1,1).' '.rand());
$stmt2->execute();
$rs2 = $stmt2->fetch(PDO::FETCH_ASSOC);
syslog(LOG_INFO,'$rs2: '.print_r($rs2,1).' '.rand());
}
catch(PDOException $e){echo(sql_error($e));}
}
echo('done');
Un paio di altri post. http://stackoverflow.com/questions/12843886/when-should-i-use-closecursor-for-pdo-statements, http://stackoverflow.com/questions/3725346/pdo-bindparam-pdo-bindvalue-and- DOP-closecursor.Neanche risponde alla domanda, ma implica "non ti preoccupare finché non cambia qualcosa e le cose non funzionano più". – user1032531
Mi spiace, ho appena realizzato che il mio vps crea lo stesso server. Ancora dovrebbe creare un errore nelle versioni alternative di PHP/MySQL, o differire quando php non sta emulando le stored procedure. Aggiornerò la domanda per riflettere una nuova comprensione. – user1032531
Non lo vedo nella tua domanda, ma questo è un problema che esiste anche (e perseguita) chiunque esegua stored procedure. Non è possibile eseguire query all'interno dei risultati di una stored procedure che può rendere le cose abbastanza difficili da aggirare. – JM4