Laravel实现批量更新多条数据
作者:娜小喵儿~ 发布时间:2023-10-23 03:23:03
前言
近期在刷新生产环境数据库的时候,需要更新表中的字段,如果对每条数据结果都执行一次update语句,占用的数据库资源就会很多,而且速度慢。
因为项目是Laravel框架,Laravel有批量插入的方法,却没有批量更新的方法,没办法只能自己实现。
准备
mysql case…when的用法
MySQL 的 case when 的语法有两种:
简单函数
CASE [col_name] WHEN [value1] THEN [result1]…ELSE [default] END
CASE [col_name] WHEN [value1] THEN [result1]…ELSE [default] END: 枚举这个字段所有可能的值
select id,status '状态值', case status
when 10 then '未开始'
when 20 then '配送中'
when 30 then '已完成'
when 40 then '已取消'
End '状态'
from table
输出结果:
搜索函数
CASE WHEN [expr] THEN [result1]…ELSE [default] END
CASE WHEN [expr] THEN [result1]…ELSE [default] END:搜索函数可以写判断,并且搜索函数只会返回第一个符合条件的值,其他case被忽略
select id,lessee_id '租户ID', case
when lessee_id <=1 then '自用系统'
when lessee_id >1 then '租用系统'
End '系统分类'
from waybill_base_info
case…when实现数据库的批量更新
更新单列的值
UPDATE base_info SET
city_id = CASE id
WHEN 1 THEN
WHEN 2 THEN
WHEN 3 THEN
END
WHERE id IN (1,2,3)
这句sql的意思是,更新city_id 字段:
如果id=1 则city_id 的值为100010,
如果id=2 则 city_id 的值为100011,
如果id=3 则 city_id 的值为100012。
即是将条件语句写在了一起。
这里的where部分不影响代码的执行,但是会提高sql执行的效率。
确保sql语句仅执行需要修改的行数,这里只有3条数据进行更新,而where子句确保只有3行数据执行。
更新多列的值
UPDATE base_info SET
city_id = CASE id
WHEN 1 THEN 100010
WHEN 2 THEN 100011
WHEN 3 THEN 100012
END,
city_name = CASE id
WHEN 1 THEN ‘北京'
WHEN 2 THEN ‘上海'
WHEN 3 THEN ‘广州'
END
WHERE id IN (1,2,3)
不过这个有个缺点 : 要注意的问题是SQL语句的长度,需要考虑程序运行环境所支持的字符串长度,当然这也可以更新mysql的设置来扩展。
Laravel实现批量更新
在model方法中封装该批量更新的方法:
//批量更新
public function updateBatch($multipleData = [])
{
try {
if (empty($multipleData)) {
Log::info("批量更新数据为空");
return false;
}
$tableName = $this->table; // 表名
$firstRow = current($multipleData);
$updateColumn = array_keys($firstRow);
// 默认以id为条件更新,如果没有ID则以第一个字段为条件
$referenceColumn = isset($firstRow['id']) ? 'id' : current($updateColumn);
unset($updateColumn[0]);
// 拼接sql语句
$updateSql = "UPDATE " . $tableName . " SET ";
$sets = [];
$bindings = [];
foreach ($updateColumn as $uColumn) {
$setSql = "`" . $uColumn . "` = CASE ";
foreach ($multipleData as $data) {
$setSql .= "WHEN `" . $referenceColumn . "` = ? THEN ? ";
$bindings[] = $data[$referenceColumn];
$bindings[] = $data[$uColumn];
}
$setSql .= "ELSE `" . $uColumn . "` END ";
$sets[] = $setSql;
}
$updateSql .= implode(', ', $sets);
$whereIn = collect($multipleData)->pluck($referenceColumn)->values()->all();
$bindings = array_merge($bindings, $whereIn);
$whereIn = rtrim(str_repeat('?,', count($whereIn)), ',');
$updateSql = rtrim($updateSql, ", ") . " WHERE `" . $referenceColumn . "` IN (" . $whereIn . ")";
Log::info($updateSql);
// 传入预处理sql语句和对应绑定数据
return DB::update($updateSql, $bindings);
} catch (\Exception $e) {
return false;
}
}
在service层拼接需要更新的数据,并调用该函数:
foreach ($taskInfo as $info) {
$cityId = $info['requirement']['city_ids'];
//此处省略n行代码
$cityInfo = ['id' => $dataId[$info['id']]['id'], 'city_id' => $cityId];
if ($cityInfo) {
$cityInfos[] = $cityInfo;
}
}
$res = $this->waybillDriverInfoModel->updateBatch($cityInfos);
}
拼接的批量更新的数组格式为:
$students = [
[‘id' => 1, ‘city_id' => ‘100010'],
[‘id' => 2, ‘city_id' => ‘100011'],
];
生成的SQL语句如下:
UPDATE base_info SET `city_id` = CASE WHEN `id` = 1 THEN 100010 WHEN `id` = 2 THEN 100011 ELSE `city_id` END WHERE `id` IN (1,2)
因为每次只操作20条数据,所以这样拼接的字符串不会太长,符合mysql的字符串长度的要求,解决问题。
本文主要讲解了Laravel实现批量更新多条数据的方法,更多关于Laravel的使用技巧请查看下面的相关链接
来源:https://blog.csdn.net/qq_28673091/article/details/100534908


猜你喜欢
- 项目环境:python3.6一、项目结构二、数据集准备数据集准备分为两步:获取图片.提取人脸.1、获取图片首先可以利用爬虫,从百度图片上批量
- 目录一、什么是 socket ?二、Socket 编程的重要概念① IP 地址② TCP/IP 端口③ 协议三、socket 编程的 API
- 如下所示:一. visualize.pyfrom graphviz import Digraphimport torchfrom torch
- 前言首先抛出几个问题:console.log(Boolean({}));console.log(Number([]));console.lo
- 有时候在读取数据库之后,针对同一结果集,在同一个页面上输出的时候可能会碰到多次输出,也就是多次执行mysql_fetch_array(),在
- 安装了pycharm之后有一个新装的python解释器,顶替了之前系统的python那样的话,原来利用pip安装的一些库会无法import.
- 表结构: CREATE TABLE [dbo].[Xtest]( [ID] [bigint] IDENTITY(1,1) NOT NULL,
- 1.安装pip我的个人桌面系统用的linuxmint,系统默认没有安装pip,考虑到后面安装requests模块使用pip,所以我这里第一步
- 1. import_table介绍上期技术分享我们介绍了MySQL Load Data的4种常用的方法将文本数据导入到MySQL,这一期我们
- 前言特点:在双主配置中,两台mysql互为主从节点。节点A是节点B的master,同时节点B也是节点A的master。安装mysql步骤略过
- 因为很多时候要涉及到url的编码和解码工作,所以自己制作了一个类,废话不多说 码上见!# coding:utf-8import urllib
- 全栈即指的是全栈工程师,指掌握多种技能,并能利用多种技能独立完成产品的人。就是与这项技能有关的都会,都能够独立的完成。全栈只是个概念,也分很
- 方法一、使用os模块的system方法:os.system(cmd),其返回值是shell指令运行后返回的状态码,int类型,0表示shel
- HTTP状态码 摘要说明成功2××  
- 需求:需要实现一个用户反馈的接口,用户通过接口提交:1.一段文字2. 一个log文件3. 多个图片找了很多ModelForm,DRF-Ser
- 本文实例为大家分享了基于numpy实现逻辑回归的具体代码,供大家参考,具体内容如下交叉熵损失函数;sigmoid激励函数基于numpy的逻辑
- Sql Server 解决“用户登录失败,错误编号18456”1.说明因密码或用户名错误而使身份验证
- 前言这里存储过程和游标的定义和作用就不介绍了,网上挺多的,只通过简单的介绍,然后用个案例让大家快速了解。实例中会具体说明变量的定义,赋值,游
- 没怎么用过这个新特性,其实也不算新啦,试试吧,现在静态类的继承很方便了<?phpclass A { protected static
- golang切片和数组拷贝基础Go 语言里面变量有两类,一类是值类型,一类是引用类型。在 Go 语言中:string、int、bool、fl