简体   繁体   中英

PDO refuses to delete a row of data (in specific table)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM