Laravel_ORM集合中的chunk方法使用陷阱
问题代码如下:
\DB::table('records')->where('status','=', 1)->chunk(50, function ($records) {
if (empty($records)) {
return;
}
//执行更新
$records->each(function ($item, $key) {
\DB::table('records')->where('id','=', $item['id'])->update(['status' => 2]);
});
});
问题分析
chunk方法解析的SQL形如:
SELECT * FROM records WHERE status = 1 OFFEST = {$offset} LIMIT {$limit}
以上代码解析的语句:
SELECT * FROM records WHERE status = 1 OFFEST = 0 LIMIT 50;
SELECT * FROM records WHERE status = 1 OFFEST = 50 LIMIT 50;
····
SELECT * FROM records WHERE status = 1 OFFEST = 50*n LIMIT 50;
如果查询条件一直在变化会导致OFFSET位移发生变化,导致错漏部分查询结果。
解决办法
$limit = 50;
while (true) {
$records = \DB::table('records')->where('status','=', 1)->limit(50)->get();
//执行更新
$records->each(function ($item, $key) {
\DB::table('records')->where('id','=', $item['id'])->update(['status' => 2]);
});
if(empty($records) || count($records) < $limit){
break;
}
}
总结
chunck 方法适用于记录查询场景,在更新记录是慎用
作者:T&D
Q Q:335749143
邮箱:tanda.arch#gmail.com(@替换#)
出处:http://www.cnblogs.com/one-villager/
*
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。