laravel按不同条件批量更新不同数据记录一下

laravle按不同条件批量更新不同数据记录一下

laravel中DB类中支持批量插入但是没有批量更新语句
如果当需要批量修改数据时,如果用循环来一条一条更新的话极大的消耗资源
下面为批量更新方法,建议分组执行 一组10-20条记录同时更新

/**
     * 批量更新
     * @param string $whereColumn 条件字段 最好用id主键
     * @param array $rows 批量修改的数据 每一行中必须包含条件列与值 例如 $rows = [['id'=>1,'image'=>'xxx','name'=>'xxx'],['id'=>2,'image'=>'xxx','name'=>'xxx','info'=>'xxxx'],['id'=>3,'其他列1'=>'xxx','其他列2'=>'xxx','其他列3'=>'xxxx']] 每行可修改不同数据
     * @return false|int 成功返回影响行数 失败返回false
     * @throws \Exception
     */
    public function updateBatch(string $whereColumn = 'id', array $rows = [])
    {
    
    
        if (empty($rows)) {
    
    
            throw new StatusTagException("data_notfound");
        }
        $tableName = DB::getTablePrefix() . $this->getTable(); // 表名


        // 取出所有需要更新的列
        $updateColumn = [];
        foreach ($rows as $row){
    
    
            $updateColumn = array_merge($updateColumn,array_keys($row));
        }
        // 去重复
        $updateColumn = array_unique($updateColumn);


        // 拼接sql语句
        $updateSql = "UPDATE " . $tableName . " SET ";
        $sets  = [];
        $bindings = [];
        $isExists = false;
        foreach ($updateColumn as $uColumn) {
    
    
            // 当前列 不等于条件列
            if($uColumn!==$whereColumn){
    
    
                $setSql = "`" . $uColumn . "` = CASE ";
                // 记录当前列 在所有行中是否存在
                $isExists = false;
                foreach ($rows as $row) {
    
    
                    // 判断是否存在 条件列
                    if(!isset($row[$whereColumn]) or is_null($row[$whereColumn]) or is_array($row[$whereColumn]) or is_object($row[$whereColumn])){
    
    
                        throw new \Exception('缺少条件');
                    }

                    // 判断当前数据组 是否存在该修改的列 存在则添加修改 不存在不添加
                    if(isset($row[$uColumn])){
    
    

                        // 判断数据格式
                        if(is_array($row[$uColumn])){
    
    
                            $row[$uColumn] = json_encode($row[$uColumn]);
                        }else if(is_object($row[$uColumn])){
    
    
                            throw new \Exception('格式错误');
                        }

                        $setSql .= "WHEN `" . $whereColumn . "` = ? THEN ? ";
                        // 条件列
                        $bindings[] = $row[$whereColumn];
                        // 修改的列 值
                        $bindings[] = $row[$uColumn];
                        // 在行中存在
                        $isExists = true;
                    }
                }
                // 当前列在所有行中不存在 抛出异常
                if(!$isExists){
    
    
                    throw new \Exception('数据不存在');
                }
                $setSql .= "ELSE `" . $uColumn . "` END ";
                $sets[] = $setSql;
            }
        }
        $updateSql .= implode(', ', $sets);
        $whereIn = collect($rows)->pluck($whereColumn)->values()->all();
        $bindings = array_merge($bindings, $whereIn);
        $whereIn = rtrim(str_repeat('?,', count($whereIn)), ',');
        $updateSql = rtrim($updateSql, ", ") . " WHERE `" . $whereColumn . "` IN (" . $whereIn . ")";
        //dump([$updateSql,$bindings,$whereIn]);
        //throw new StatusTagException('missing_data');
        // 传入预处理sql语句和对应绑定数据
        return DB::update($updateSql, $bindings);

    }

使用示例

$updateSkus = [['id'=>1,'image'=>'xxx','price'=>'xxx'],['id'=>2,'image'=>'xxx','price'=>'xxx','info'=>'xxxx'],['id'=>3,'其他列1'=>'xxx','其他列2'=>'xxx','其他列3'=>'xxxx']]
            if (!empty($updateSkus)) {
    
    
                // 分组更新 每组最大20条
                $max = 20;
                $endKey = count($updateSkus) -1;
                $lsSkus = [];
                foreach ($updateSkus as $k=>$sku){
    
    
                    $lsSkus[] = $sku;
                    if(count($lsSkus) === $max or $k === $endKey){
    
    
                        $num = (new GoodsSku())->updateBatch('id',$lsSkus);
                        if (empty($num) or $num !== count($lsSkus)) {
    
    
                        	// 抛出异常 执行回滚
                            throw new \Exception('更新失败');
                        }
                        $lsSkus = [];
                    }
                }
            

猜你喜欢

转载自blog.csdn.net/it2299888/article/details/113168041