How to retrieve PDO result==false? - php

I'm converting my mysql_query() calls to PDO but don't understand how to get a false result on failure. This is my code:
$STH = $DBH->query("SELECT * FROM articles ORDER BY category");
$STH->setFetchMode(PDO::FETCH_ASSOC);
$DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
This is what I'm trying to do but does not work:
if($STH==false) {
foreach($dbh->errorInfo() as $error) {
echo $error.'<br />';
}
}

When using PDO the nature of querying usually goes down like so:
try
{
$STH = $DBH->prepare("SELECT * FROM articles ORDER BY category"); //Notice the prepare
$STH->setFetchMode(PDO::FETCH_ASSOC);
//No need to silent as the errors are catched.
if($STH === false) //Notice the explicit check with !==
{
//Do not run a foreach as its not multi-dimensional array
$Error = $DBH->errorInfo();
throw new Exception($Error[2]); //Driver Specific Error
}
}catch(Exception $e)
{
//An error accured of some nature, use $e->getMessage();
}
you should read errorInfo very carefully and study the examples.

Related

How to execute multiple queries using PDO for Sql Server

I'd like to execute some queries that doesn't return result set, and then execute a real query, and fetch its result.
Here is an exemple that doesn't work :
<?php
try {
$db = new PDO('dblib:host=myhost;dbname=master','user','password');
$query = "declare #entier int = 1;";
$db->exec($query);
$query = "select #entier;";
$stmt = $db->query($query);
$rows = $stmt->fetchAll();
print_r($rows);
}
catch (PDOException $e) {
print ($e->getMessage());
}
catch (Exception $e) {
print ($e->getMessage());
}
?>
This code neither doesn't work :
try {
$db = new PDO('dblib:host=myhost;dbname=master','user','password');
$query = "declare #entier int = 1; select #entier;";
$stmt = $db->query($query);
$rows = $stmt->fetchAll();
print_r($rows);
}
catch (PDOException $e) {
print ($e->getMessage());
}
catch (Exception $e) {
print ($e->getMessage());
}
?>
But this code works :
<?php
try {
$db = new PDO('dblib:host=myhost;dbname=master','user','password');
$query = "select 1;";
$stmt = $db->query($query);
$rows = $stmt->fetchAll();
print_r($rows);
}
catch (PDOException $e) {
print ($e->getMessage());
}
catch (Exception $e) {
print ($e->getMessage());
}
?>
Thanks for your help
I know this is old, but for other people finding this from Google: you need to use PDOStatement::nextRowset to iterate over the result sets from your multiple queries.
However, it seems there are memory issues when using nextRowset with dblib in some versions (it tried to allocate 94Tb in my case...), so I ended up re-engineering to avoid multiple SQL queries altogether (instead duplicating the value of the DECLARE where it was being used).
PDO::query docs (http://php.net/manual/it/pdo.query.php) say
PDO::query() executes an SQL statement in a single function call, returning the result set (if any) returned by the statement as a PDOStatement object.
This could mean that you can execute with query() both queries with and without result

No error is thrown on inexistant table

I must miss something but I have a very strange behaviour with PDO (MySQL).
$req = null;
try {
$sql = 'INSERT INTO inexistant_table (idmember) VALUES(:idmember)';
$req = $db->prepare($sql);
$req->bindParam(':idmembre', $_SESSION['ID']);
$req->execute();
}
catch (PDOException $e) {
echo 'exception';
}
if( !$req ) {
echo 'false';
}
echo 'success';
Then I don't get any error, it only prints 'success'. Any idea?
EDIT: $db->errorCode() returns 00000.
The outcome is explained as such,
Exceptions are not enabled - no "exception"
To enable exceptions, as per Fred -ii-'s comment, thanks! ;-)
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
(Also see Reference - frequently asked questions about PDO)
The wrong value is being checked - no "false"
The $req variable represents the prepared statement object, not the result of such executing such a statement. Compare with the following that checks the result.
$result = $req->execute();
// ..
if (!$result) { /* fail! */ }

select interbase and insert to mysql show 1 record only

I try to get data from another machine which use interbase. I'm using PDO to insert the interbase value to Mysql. But just one record which inserted to mysql. Why?
$stmt = "SELECT FIRST 10 TRIM(LINE_NAME) as LINE_NAME, TRIM(MODEL_NAME) as MODEL_NAME, TRIM(PROD_NO) as PROD_NO,
TRIM(LOT_SIZE_IN) as LOT_SIZE_IN,TRIM(START_SERIAL) as START_SERIAL,
TRIM(SERIAL_NO_LOW) as SERIAL_NO_LOW, TRIM(SERIAL_NO_UP) as SERIAL_NO_UP, TRIM(PROD_DATE) as PROD_DATE
FROM DOC_TO";
$sth = ibase_query($dbh, $stmt);
// CREATE AN ARRAY OF OBJECTS
if($sth === FALSE) {
die(ibase_errmsg()); // TODO: better error handling
}
while ($row = ibase_fetch_object($sth)) {
$newvalues[] = $row;
}
$dbh = new PDO('mysql:host=localhost;dbname=qdbase', 'root', 'JeinQA123');
$sql="TRUNCATE TABLE `schedule`";
$stmt = $dbh->query($sql);
if($stmt){echo "connected";}
else{echo "failed";}
// PREPARE A QUERY
$qry2 = "INSERT INTO schedule (line,model,lotno,qty,serial,seriallow,serialup,date )
VALUES (:LINE_NAME, :MODEL_NAME, :PROD_NO,:LOT_SIZE_IN,:START_SERIAL,:SERIAL_NO_LOW,:SERIAL_NO_UP,:PROD_DATE)";
$stmt = $dbh->prepare($qry2);
// USE THE ARRAY OF OBJECTS
foreach ($newvalues as $obj)
{
// BIND THE OBJECT PROPERTIES INTO THE QUERY
$stmt->bindParam('LINE_NAME', $obj->LINE_NAME);
$stmt->bindParam('MODEL_NAME', $obj->MODEL_NAME);
$stmt->bindParam('PROD_NO', $obj->PROD_NO);
$stmt->bindParam('LOT_SIZE_IN', $obj->LOT_SIZE_IN);
$stmt->bindParam('START_SERIAL', $obj->START_SERIAL);
$stmt->bindParam('SERIAL_NO_LOW', $obj->SERIAL_NO_LOW);
$stmt->bindParam('SERIAL_NO_UP', $obj->SERIAL_NO_UP);
$stmt->bindParam('PROD_DATE', $obj->PROD_DATE);
/*I try to add this inside foreach*/
try
{
$stmt->execute();
}
// IF THERE IS AN EXCEPTION THROWN BY PDO
catch (PDOException $exc)
{
// IF THE EXCEPTION NUMBER IS NOT "DUPLICATE UNIQUE"
if ($exc->errorInfo[1] != 1062)
{
$msg = "FAIL: $qry " . PHP_EOL . $exc->getmessage();
trigger_error($msg, E_USER_ERROR);
}
}
}
Try the following
// make sure PDO is set to throw exceptions
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $dbh->prepare($qry2);
foreach ($newvalues as $obj) {
try {
$stmt->execute(array(
':LINE_NAME' => $obj->LINE_NAME,
':MODEL_NAME' => $obj->MODEL_NAME,
':PROD_NO' => $obj->PROD_NO,
':LOT_SIZE_IN' => $obj->LOT_SIZE_IN,
':START_SERIAL' => $obj->START_SERIAL,
':SERIAL_NO_LOW' => $obj->SERIAL_NO_LOW,
':SERIAL_NO_UP' => $obj->SERIAL_NO_UP,
':PROD_DATE' => $obj->PROD_DATE
));
} catch (PDOException $e) {
$errorInfo = $stmt->errorInfo();
if ($errorInfo[1] != 1062) {
throw $e;
}
}
}
I'm not entirely sure that 1062 is the error code to be checking for. In the past, I've used 1586 to detect unique constraint violations. Trial and error will discover the right value to check.
You were also using $stmt->errorInfo as a property instead of the method $stmt->errorInfo().

Sqlite PDO query returns no results

Getting no results no matter how broad my query
PHP: 5.3
Sqlite3: 3.6
PDO: 5.3.3
I would think this should be a very simple process but even looking around I still don't know why I'm getting 0 results. Here is my code:
<?php
$sqlite = new PDO('sqlite:/example.db');
$result = $sqlite->query('SELECT * from foo');
if(!$result)
{
echo 'fail';
return false;
}
?>
Any ideas on what I am doing wrong? The 'foo' table will only have four columns, and this test db only has one table. Running the query in sqlite displays the results fine.
You have to execute the statement first than fetch the result.
You might add try/catch block around the execute method call. and do some error handling.
Here's an example of catching an Exception. Do not use it as a design guideline.
<?php
try
{
$sqlite = new PDO('sqlite:/example.db');
}
catch (PDOException $e)
{
echo 'Connection failed: ' . $e->getMessage();
}
$statement = $sqlite->prepare('SELECT * from foo');
try
{
$statement->execute();
}
catch(PDOException $e)
{
echo "Statement failed: " . $e->getMessage();
return false;
}
$result = $statement->fetchAll();
var_dump($result);
?>

How can I use prepared statements combined with Transactions with PHP?

My goal is to use a transaction and a prepared statement simultaneously, to achieve both integrity of data, and prevention of SQL injection.
I have this:
try {
$cnx = new PDO($dsn,$dbuser,$dbpass);
$cnx->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$cnx->beginTransaction();
$cnx->query("SELECT * FROM users WHERE username=$escaped_input");
$cnx->query("SELECT * FROM othertable WHERE some_column=$escaped_input_2");
$cnx->commit();
}
catch (Exception $e){
$cxn->rollback();
echo "an error has occured";
}
I would like to incorporate the query as one would with a prepared statement:
$stmt=$cxn->prepare("SELECT * FROM users WHERE username=?");
$stmt->execute(array($user_input));
$stmt_2=$cxn->prepare("SELECT * FROM othertable WHERE some_column=?");
$stmt_2->execute(array($user_input_2));
How can I achieve that?
Edit
I get this error:
PHP Parse error: syntax error, unexpected T_CATCH
Here is my updated code:
try
{
$cnx = new PDO($dsn,$dbuser,$dbpass);
$cnx->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$cnx->beginTransaction();
$stmt=$cnx->prepare("SELECT * FROM users WHERE username=?");
$stmt->execute(array($username));
$cnx->commit();
while ($row=$stmt->fetch(PDO::FETCH_OBJ)){
echo $stmt->userid;
}
catch(Exception $e) {
if (isset($cnx))
$cnx->rollback();
echo "Error: " . $e;
}
Just call "execute" after you call "beginTransaction".
Where you call "prepare" doesn't really matter.
Here's a complete example:
http://php.net/manual/en/pdo.begintransaction.php
EXAMPLE:
try {
$cnx = new PDO($dsn,$dbuser,$dbpass);
$cnx->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$cnx->beginTransaction();
$stmt=$cxn->prepare("SELECT * FROM users WHERE username=?");
$stmt->execute(array($user_input));
$stmt_2=$cxn->prepare("SELECT * FROM othertable WHERE some_column=?");
$stmt_2->execute(array($user_input_2));
$cnx->commit();
}
catch (Exception $e){
$cxn->rollback();
echo "an error has occurred";
}
PS:
1) I'm assuming, of course, that $user_input and $user_input_2 are available immediately. You don't want your transaction hanging open unnecessarily long ;)
2) Based on your comment reply above, I think you might be confusing "execute" and "begin tran/commit". Please look at my link.
3) Do you even need a transaction? You're just doing two "select's".
4) Finally, why not do one "join" (or union, if compatible) instead of two "select's"?
try
{
$cnx = new PDO ($dsn,$dbuser,$dbpass);
$cnx->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$cnx->beginTransaction ();
$stmt = $cnx->prepare ("SELECT * FROM users WHERE username=?");
$stmt->execute(array($username));
$cnx->commit();
while ($row = $stmt->fetch (PDO::FETCH_OBJ)){
echo $row->userid;
}
}
catch (Exception $e) {
if (isset ($cnx))
$cnx->rollback ();
echo "Error: " . $e;
}
}
Did you mean this?
try {
$cnx = new PDO($dsn,$dbuser,$dbpass);
$cnx->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$cnx->beginTransaction();
$stmt=$cnx->prepare("
SELECT * FROM users, othertable
WHERE users.username=?
AND othertable.some_column=?");
$stmt->execute(array($user_input,$user_input_2));
$cnx->commit();
}
catch (Exception $e){
$cnx->rollback();
echo "an error has occured";
}
That is assuming that the two tables data does not have duplicate field names, otherwise you're going to have to use:
SELECT users.field1 as u_field1, othertable.field1 as o_field1 FROM users, othertable
WHERE users.username=?
AND othertable.some_column=?

Categories