在For循环中运行查询

时间:2017-02-01 20:05:09

标签: php mysql pdo

我试图在某些代码中删除for循环中运行的MySQL查询。

但我不确定如何最好地实现这一目标。

使用带有命名参数的PHP PDO,如何存储查询,然后在循环后以批处理方式运行它们?所以在for循环中发生的唯一事情就是构建了查询,但是在循环结束之后才执行它?

这是示例代码:

Route::group(['middleware' => ['web']], function() {
    Auth::routes();
    Route::get('/', function () {
        return view('welcome');
    });
    Route::get('/dashboard', 'admin\adminRootController@dashboard')->middleware('auth');
});

2 个答案:

答案 0 :(得分:2)

我最初的反应是:为什么这样做?你的动机是什么?简单地避免循环中的SQL,或者您是否想要避免某些操作问题?

您的确切查询转换为单个查询并不容易,因为您确实有必须匹配的IDOrder元组的元组才能被删除。另请注意,预准备语句通常不接受任意数量的参数,因此即使您能够将查询转换为DELETE FROM table WHERE (ID=1 AND Order=1000) OR (ID=4 AND Order=1234)...形式,您也必须以某种方式解决如何填充第一个参数,第二,第三......占位符。此外,您将被迫动态生成该预准备语句,这可能与安全性准备语句的执行方式相反。

如果您遇到性能问题,因为一个接一个地删除1000个条目会产生很大的影响,那么还有其他选择:如果您将删除包装在一个单独的事务中,那么删除多少条目可能并不重要 - 提交事务后,所有这些都将被删除。另请注意,使用预准备语句是加速数据库操作的一种方法 - 但只有在循环之前只准备一次,并且在循环内部,您只会反复传递新参数。

所以要把它包起来:如果你想要解决的编程问题可以通过循环更好地解决,那么在循环中撤消SQL并不是最好的事情,并且没有其他相关的问题。如果存在这样的问题,则必须对其进行分析和提及 - 删除循环不是一个自动成功的故事。

答案 1 :(得分:0)

我想你需要确保所有查询都被执行,换句话说你需要一个交易:

$conn->beginTransaction();
try{
    $query  = "DELETE FROM table WHERE ID=:id AND Order=:order";
    $stmt = $conn->prepare($query);

    for($i=$rowcount;$i>0;$i--){ 
        $id = $array[$i];
        $stmt->execute(['id' => $id,'order'=>$i]);
    }

    $conn->commit();
}
catch(Exception $ex){
    $conn->rollBack();
}