使用PDO运行查询并根据条件执行大量操作

时间:2018-03-04 02:58:08

标签: php mysql pdo

我正在尝试重构脚本并将PDO放到位,但我对它并不十分熟悉。

我已经得到了一些相当简单的查询,但我正在尝试在顶部建立我的基本SELECT查询,然后使用循环和条件根据所选值执行大量操作。我现在的问题是根据2个条件删除记录。

我的选择返回正确的记录,如果我回显符合条件的记录,则打印出来。但是当我运行我的脚本的这部分时,它会删除表中的所有记录,而不仅仅是那些受条件影响的记录:

date_default_timezone_set('America/New_York');

//PDO statement to select from order_status
$ordStatSql = 'SELECT order_id, order_status, is_placement, date_updated 
                FROM order_status';
try{
$ordStat = $MysqlConn->prepare($ordStatSql);
$result = $ordStat->execute();
}
catch(PDOException $ex)
{
    echo "QUERY FAILED!: " .$ex->getMessage();
}

while($row = $ordStat->fetch(PDO::FETCH_ASSOC))
    {
        if(strtotime($row['date_updated']) > strtotime('-5 day')  && $row['is_placement'] == 1){

            $deleteOld = 'DELETE FROM Order_status';
            try{
            $delete = $MysqlConn->prepare($deleteOld);
            $result = $delete->execute();
            $count = $delete->rowcount();
            echo "Records Deleted: " . $count;
            }
            catch(PDOException $ex)
            {
                echo "QUERY FAILED!: " .$ex->getMessage();
            }

        }
    }

基本上,如果SELECT中的一行将is_placement设置为1且date_updated超过5天,我只想删除该记录。

我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

问题是你正在运行

DELETE FROM Order_status

每行符合您的条件。该查询只会删除order_status中的所有内容,这就是您遇到的问题。立即解决方案是删除循环中当前行的order_id行:

$deleteOld = 'DELETE FROM Order_status WHERE order_id = ?';
try {
    $delete = $MysqlConn->prepare($deleteOld);
    $result = $delete->execute([
        $row["order_id"],
    ]);
    // snip

请注意使用prepared statements

但是,为了避免使用N+1 problem,您应该只使用其中的条件执行一个查询。例如,如果我正确理解了条件,那么这样的查询将如下所示:

DELETE FROM order_status WHERE is_placement = 1 AND date_updated > DATE_SUB(NOW(), INTERVAL 5 DAY)

然后,您只需要执行一个查询(甚至不需要SELECT)。