Okay, I am stumped with this one. I have a table in my database where I cannot seem to delete rows via PDO (I have noticed this behaviour for a few weeks now, it was working perfectly before that).
My PHP Code is this:
// Echo's have been added for testing.
try{
$dbh = new PDO($hostname, $username, $password);
$sql="delete from sources where workFlowID=".$ID.";";
$numRows=$dbh->exec($sql);
echo "There were $numRows deleted with: $sql <br><br>";
$sql="delete from workflow where id=".$ID." limit 1;";
// I have only put the 'or die' section in this today to try to see where
// it was having problems. It carries through happily as the output
// below shows.
$numRows=$dbh->exec($sql) or die(print_r($dbh->errorInfo(), true));
// This is the problem delete...
echo "There were $numRows deleted with: $sql <br><br>";
$dbh=null;
}
catch(PDOException $e){
echo 'Error : '.$e->getMessage();
exit();
}
With the output of:
There were 1 deleted with: delete from sources where workflowid=1;
There were 1 deleted with: delete from workflow where id=1 limit 1;
However, when I look in the database, I still see my record sitting in my workflow
table.
I have checked and double checked the data types. ID and workflowID are both ints. They are being supplied with the same variable a few lines apart.
I thought it might be a permissions issue, so I have blanket covered that with the following:
mysql> grant all privileges on storeProcess.* to 'myusername'@'localhost' with
grant option;
Query OK, 0 rows affected (0.19 sec)
I then thought it might be some funky timing/overload/whothehellknowswhat issue, so I created a trigger on the workflow table to do the work of the application and clean up other tables. I then changed my PHP code to this:
// Echo's have been added for testing.
try{
$dbh = new PDO($hostname, $username, $password);
$sql="delete from workflow where id=".$ID." limit 1;";
$numRows=$dbh->exec($sql) or die(print_r($dbh->errorInfo(), true));
echo "There were $numRows deleted with: $sql <br><br>";
$dbh=null;
}
catch(PDOException $e){
echo 'Error : '.$e->getMessage();
exit();
}
Now the output is:
There were 1 deleted with: delete from workflow where id=1 limit 1;
But again, the record is still there.
mysql> select count(*) from workflow where id=1;
+----------+
| count(*) |
+----------+
| 1 |
+----------+
1 row in set (0.00 sec)
I of course have no problems deleting the record from the console with the exact same command when I am logged in using the usename/password of the account that PDO is using (the trigger works fine and removes data from the remaining tables as well):
mysql> delete from workflow where ID=1;
Query OK, 1 row affected (0.00 sec)
mysql> select count(*) from workflow where id=1;
+----------+
| count(*) |
+----------+
| 0 |
+----------+
1 row in set (0.00 sec)
So what is going wrong?
This is running on my work desktop (Win XP, nothing fancy, standard type SOE from large corporation).
I am not using any transactions during these queries. Additionally there are only a few users using the app and it doesn't hit high CPU during anything.
I will be taking the code and schema home to test it under linux and will post the results when I get back.
Update: I have just moved it to my linux system here at home. No change at all.
Edit:
I have changed my code as suggested to this:
try{
$dbh = new PDO($hostname, $username, $password);
$dbh->setAttribute(PDO::ATTR_AUTOCOMMIT, true);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql="delete from sources where workflowid=".$ID.";";
//echo $sql."<br><br>";
$numRows=$dbh->exec($sql);
echo "There were $numRows deleted with:<b> $sql </b><br><br>";
$sql="delete from workflow where id=".$ID." limit 1;";
$numRows=$dbh->exec($sql);
echo "There were $numRows deleted with:<b> $sql </b><br><br>";
$sql="delete from workflow where id=".$ID." limit 1;";
$numRows=$dbh->exec($sql);
echo "There were $numRows deleted with:<b> $sql </b><br><br>";
$dbh=null;
}
catch(PDOException $e){
echo 'Error : '.$e->getMessage();
//exit();
}
I ran it with the following output:
There were 601 deleted with: delete from sources where workflowid=77;
There were 1 deleted with: delete from workflow where id=77 limit 1;
There were 0 deleted with: delete from workflow where id=77 limit 1;
The row was still not deleted:
mysql> select count(*) from workflow where id=77;
+----------+
| count(*) |
+----------+
| 1 |
+----------+
1 row in set (0.00 sec)
The PDO::exec()
function returns the number of affected rows, including 0 if no rows are affected.
A line like this will die()
because exec
will return 0
which is interpreted as boolean false.
$dblink->exec("UPDATE `sometable` SET `somecolumn`=0 WHERE `somecolumn`=0") or die("Never use die for error handling.");
The best error handling practice for PDO is to use PDO exceptions. Enable PDO exceptions (of PDOException class, see docs) like this:
//enable Exception mode (uncaught exceptions work just like die() with the benefit of giving you details in logs of where execution was stopped and for what reason)
$pdoDBHandle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Remove or die()
and exit();
and enable exception mode. I bet this will fix your "weird" problem. Also take a look at throwing Exceptions in PHP, even with procedural code (to replace die()
and exit()
.
BTW exit
stops execution just like die
, except it is usefull in CLI mode because it returns a success/error code to the operating system. It really isn't meant for error handling.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.