zoukankan      html  css  js  c++  java
  • 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/
    * 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    3.14周末作业
    3.13作业
    文件处理
    字符编码
    基本数据类型总结
    基本数据类型--------------------集合set()
    python入门009
    作业009
    python入门008
    作业008
  • 原文地址:https://www.cnblogs.com/one-villager/p/7567042.html
Copyright © 2011-2022 走看看