I've just migrated from MySQL to newer MariaDB and all my websites are now showing:
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.
I googled this error and tried doing what people suggested.
So I changed my code to use PDO's closeCursor().
I tried using PDO::MYSQL_ATTR_USE_BUFFERED_QUERY and nothing works.
And here's how my constructor looked:
$pdo = new PDO('mysql:host=' . $host . ';dbname=' . $db . ';port=' . $port, $user, $pass,
array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8;SET SESSION time_zone="system"',
PDO::MYSQL_ATTR_LOCAL_INFILE => true
));
I changed it to
$pdo = new PDO('mysql:host=' . $host . ';dbname=' . $db . ';port=' . $port, $user, $pass,
array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8, SESSION time_zone="system"',
PDO::MYSQL_ATTR_LOCAL_INFILE => true
));
and it does work now.
I am posting my solution here because all other places have "wrong" ones.
So the difference is instead of having
'SET NAMES utf8;SET SESSION time_zone="system"'
in PDO::MYSQL_ATTR_INIT_COMMAND I have:
'SET NAMES utf8, SESSION time_zone="system"'
and everything's fine now.
Related
From what I understood, using PDO should be the same result regardless of what DB I am using. I tested this in the following code, which I have connected to two separate DB's.
$sth = $pdo->query('SELECT * FROM posts');
while($result = $sth->fetch(PDO::FETCH_BOTH)){
echo $result[1] . '<br>';
};
MySQL DB:
$dsn = 'mysql:host=' . $server . ';dbname=' . $dbname;
$pdo = new PDO($dsn, $username, $password);
Firebird DB:
$dsn = "firebird:dbname=" . $server . ":" . $dbname;
$pdo = new PDO($dsn, $username, $password);
The MySQL connection worked fine, while the Firebird connection worked only with numbered Arrays - FETCH_NUM, and FETCH_BOTH when using index positions. Is this how its supposed to be or am I doing something wrong with my Firebird connection? I will need to work with the Firebird DB in the future, so this really frustrates me. Thank you for all comments.
In Firebird, by default, mainly from historical reasons, unless you use double quotes on object names (field names, tables, etc...), they are uppercase-d and stored internally in uppercase.
Accordingly, the column names you receive in result set are in uppercase, so you should address them in upper-case like $row['FIELD_NAME'].
Alternatively, in PHP, PDO driver have a special flag used on connection, PDO::ATTR_CASE => PDO::CASE_LOWER/NATURAL/UPPER that adjust the needed case internally for you.
For example:
$source = $d['kind'].':'.'dbname='.$d['host'].':'.$d['base'].';charset='.$d['charset'];
$options = $d['options'] + [
\PDO::ATTR_CASE => \PDO::CASE_LOWER,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION
];
$connection = new \PDO($source, $d['user'], $d['password'], $options);
Firebird is not alone doing this. Oracle also stores by default metadata in uppercase. Some DBMSes have options, others in lower-case by default.
I have a utf8 json file containing some stuff like that :
"type":"Feature","geometry":{"type":"LineString","coordinates":[[-73.6371999890417,45.451049968774],[-73.6362864025022,45.4507004803266]]},"properties":{"FIN_GCH":191,"TYP_VOIE":"avenue","LIM_GCH":"Montréal-Ouest","NOM_VOIE":"Brock","CLASSE":0,"DEB_DRT":0,"FIN_DRT":0,"LIM_DRT":"Montréal-Ouest","LIE_VOIE":"","DEB_GCH":173,"ID_TRC":1602102,"DIR_VOIE":"Sud","SENS_CIR":-1}}
,{"type":"Feature","geometry":{"type":"LineString","coordinates":[[-73.6382813452807,45.4514760942107],[-73.6371999890417,45.451049968774]]},"properties":{"FIN_GCH":171,"TYP_VOIE":"avenue","LIM_GCH":"Montréal-Ouest","NOM_VOIE":"Brock","CLASSE":0,"DEB_DRT":150,"FIN_DRT":152,"LIM_DRT":"Montréal-Ouest","LIE_VOIE":"","DEB_GCH":143,"ID_TRC":1602103,"DIR_VOIE":"Sud","SENS_CIR":-1}}
With the help of a php script, i put all the data in a mysql UTF8 database but even so, the entries have weird accents : instead of Montréal-Ouest i have Montréal-Ouest
Do you have any idea what is the problem please ?
Thank you
I had to set a utf8 connection with the server by setting the options array like this
$options = array(
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
);
$connection = new PDO( $dns, $user, $password, $options );
Thanks to CBroe
I'm experimenting with loading a table from a file, and having difficulty. The code below is trying to take an existing database and copy it to a temporary table, then replace the original with imported data from a .csv file, and then I've got more work to do comparing the two tables before I let go of the temporary one. (Hints welcome if I should do this a different way). I get the error:
'SQLSTATE[HY000]: General error: 2014 Cannot execute queries while
other unbuffered queries are active. Consider using
PDOStatement::fetchAll()...'
I've tried many of the suggestions from similar questions, but haven't cracked it yet. Thanks for your help! Here's my code:
<?php
//database connection
$data_source = 'mysql:host=localhost;dbname=myDB';
$db_user = 'root';
$db_password = 'pass';
$conn = new PDO($data_source, $db_user, $db_password,
array(PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_PERSISTENT));
if ( isset($_GET['submit']) ){
$stmt = $conn->prepare("CREATE TEMPORARY TABLE mfsw_dupe AS SELECT * FROM mfsw_test");
$stmt->execute();
$stmt = $conn->prepare("TRUNCATE mfsw_test");
$stmt->execute();
$stmt = $conn->prepare("LOAD DATA LOCAL INFILE 'C:\\xampp\htdocs\assets\mfsw_test.csv' INTO TABLE mfsw_test
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
IGNORE 1 LINES");
$stmt->execute();
}
?>
After trying all the recommended solutions to this problem, I found that the answer was to set the PDO::ATTR_EMULATE_PREPARES option to true.
That got rid of "unbuffered queries" error, but it then started reporting a "LOAD DATA LOCAL INFILE forbidden" error on the LOAD query.
The solution to that was to set the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY option to true as well.
In short, your initial connection should look like this:
$conn = new PDO($data_source, $db_user, $db_password,
array(PDO::ATTR_EMULATE_PREPARES => true,
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_PERSISTENT));
I don't understand why these options are necessary, but they worked for me.
I have had exactly the same problem, tried everything mentioned above and a lot more and still couldn't avoid the "Cannot execute queries while other unbuffered queries are active" error.
However, after several hours of googling, I got it working - instead of using a prepared statement, or just query, I used 'exec' to run the 'LOAD DATA LOCAL INFILE' statement:
$stmt = $conn->exec($sql_import_csv);
I didn't need any of the aforementioned changes to the PDO options - this is my options array:
$options = array(
PDO::ATTR_EMULATE_PREPARES => false,
PDO::MYSQL_ATTR_SSL_CA => "xxxxxxxx.crt.pem",
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_LOCAL_INFILE => true
);
Hope this helps someone else out there.
I'm following a tutorial that is teaching PDO but I'm stuck at a very early point.
Referring to the code below I have diagnosed the problem down to the DB selected.
When I run print_r($query); there is no output and initallally I thought the problem was that the script wasn't connecting to the MySql server at all but then I learned if I change anything in host, user or pass I get an error message, but no matter what I change related to the database nothing happens and no error messages are displayed.
<?php
error_reporting(E_ALL);
$config['db'] = array(
'host' => 'xxxx',
'user' => 'xxxx',
'pass' => 'xxxx',
'database' => 'xxxx'
);
$db = new PDO('mysql:host=' . $config['db']['host'] . ';database=' . $config['db']['database'],$config['db']['user'], $config['db']['pass']);
$query = $db->query("SELECT `subscribers`.`first_name` FROM `subscribers`");
print_r($query);
echo 'Anything';
?>
If anyone could show me what Im doing wrong I'd be most appreciative and I thank you in advance.
BTW, I am SURE that SELECT subscribers.first_name FROM subscribers is correct as this works when I insert it into the mysql tab within php MyAdmin
I believe the DSN parameter for database name is called dbname, not database.
Try this:
$db = new PDO('mysql:host=' . $config['db']['host'] . ';dbname=' . $config['db']['database'],$config['db']['user'], $config['db']['pass']);
After creating a connection with database you need to create a statement, set query, bind values(optional), execute the query and fetch the result. In your case:
$db = new PDO('mysql:host=' . $config['db']['host'] . ';database=' . $config['db'] ['database'],$config['db']['user'], $config['db']['pass']);
$query = $db->prepare("SELECT `subscribers`.`first_name` FROM `subscribers`");
$query->execute();
$result = $query->fetchAll();
var_dump($result);
How to rewrite this in pdo:
$con = mysql_connect("localhost:".$LOCAL_DB_PORT, $LOCAL_DB_USER, $LOCAL_DB_PASS);
mysql_select_db("xnews", $con);
mysql_query("set names utf8", $con);
What about something like this :
$db = new PDO('mysql:dbname=xnews;host=localhost;port=' . $LOCAL_DB_PORT, $LOCAL_DB_USER, $LOCAL_DB_PASS);
$db->query('set names utf8');
To open a connection, you have to instanciate PDO, using its constructor, which receives a DSN as first parameter.
And, then, to send queries, you can use the PDO::query method.
Or, for the UTF-8 part, maybe you could use the fourth parameter to PDO::__construct, like this :
$db = new PDO('mysql:dbname=xnews;host=localhost;port=' . $LOCAL_DB_PORT,
$LOCAL_DB_USER,
$LOCAL_DB_PASS,
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'")
);
See the list of specific stuff for the MySQL Driver, amongst which there is this one :
PDO::MYSQL_ATTR_INIT_COMMAND
Command to execute when connecting to
the MySQL server. Will automatically
be re-executed when reconnecting.