我试图在某些代码中删除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');
});
答案 0 :(得分:2)
我最初的反应是:为什么这样做?你的动机是什么?简单地避免循环中的SQL,或者您是否想要避免某些操作问题?
您的确切查询转换为单个查询并不容易,因为您确实有必须匹配的ID
和Order
元组的元组才能被删除。另请注意,预准备语句通常不接受任意数量的参数,因此即使您能够将查询转换为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();
}