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()becauseexecwill return0which is interpreted as boolean false.The best error handling practice for PDO is to use PDO exceptions. Enable PDO exceptions (of PDOException class, see docs) like this:
Remove
or die()andexit();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 replacedie()andexit().BTW
exitstops execution just likedie, 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.