前言

近期在刷新生产环境数据库的时候,需要更新表中的字段,如果对每条数据结果都执行一次update语句,占用的数据库资源就会很多,而且速度慢,显得也不高大上。

因为项目是Laravel框架,Laravel有批量插入的方法,却没有批量更新的方法,没办法只能自己实现。

准备

mysql case…when的用法

MySQL 的 case when 的语法有两种:

  1. 简单函数
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

输出结果:

  1. 搜索函数
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 SETcity_id = CASE idWHEN 1 THEN 100010WHEN 2 THEN 100011WHEN 3 THEN 100012END
WHERE id IN (1,2,3)

这句sql的意思是,更新city_id 字段:

  1. 如果id=1 则city_id 的值为100010,
  2. 如果id=2 则 city_id 的值为100011,
  3. 如果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的字符串长度的要求,解决问题。

本文参考:https://blog.csdn.net/byywcsnd/article/details/78231429

Laravel批量更新多条数据相关推荐

  1. mysql如何更新两条数据_mysql根据查询结果批量更新多条数据(插入或更新)

    mysql根据查询结果批量更新多条数据(插入或更新) 1.1 前言 mysql根据查询结果执行批量更新或插入时经常会遇到1093的错误问题.基本上批量插入或新增都会涉及到子查询,mysql是建议不要对 ...

  2. laravel批量更新多条记录

    写在前面 熟悉laravel的童鞋都知道,laravel有批量一次性插入多条记录,却没有一次性按条件更新多条记录. 是否羡慕thinkphp的saveAll,是否羡慕ci的update_batch,但 ...

  3. mysql命令行批量添加数据_mysql命令行批量插入100条数据命令

    先介绍一个关键字的使用: delimiter 定好结束符为"$$",(定义的时候需要加上一个空格) 然后最后又定义为";", MYSQL的默认结束符为" ...

  4. android动态更新数据库数据,Android数据库更新——上万条数据的插入

    在实际情况下,很可能遇到会向一个表中插入10万条数据,而这样的数据库更新,如果用寻常的方式,在SQLiteOpenHelper.onUpdate()方法中不断的执行SQL语句,那么效率是可想而知的,甚 ...

  5. mysql更新多条数据6_mysql语句:批量更新多条记录的不同值

    mysql更新语句很简单,更新一条数据的某个字段,一般这样写: 如果更新同一字段为同一个值,mysql也很简单,修改下where即可: 这里注意 'other_values' 是一个逗号(,)分隔的字 ...

  6. mysql 批量更新数据 备份_mysql 批量更新与批量更新多条记录的不同值实现方法...

    批量更新 mysql更新语句很简单,更新一条数据的某个字段,一般这样写: UPDATE mytable SET myfield = 'value' WHERE other_field = 'other ...

  7. MySql数据库Update批量更新与批量更新多条记录的不同值实现方法

    批量更新 mysql更新语句很简单,更新一条数据的某个字段,一般这样写: UPDATE mytable SET myfield = 'value' WHERE other_field = 'other ...

  8. mysql批量条件字段_mysql批量更新多条记录的同一个字段为不同值的方法

    首先mysql更新数据的某个字段,一般这样写: UPDATE mytable SET myfield = 'value' WHERE other_field = 'other_value'; 也可以这 ...

  9. 批量更新多条记录的不同值

    mysql更新语句很简单,更新一条数据的某个字段,一般这样写: 1 UPDATE mytable SET myfield = 'value' WHERE other_field = 'other_va ...

最新文章

  1. python 四种逐行读取文件内容的方法
  2. 人类快感程度体验等级
  3. 居然还有人在用 System.out.println打日志的吗?
  4. Libevent事件的创建-scoke服务的创建-特征的获取和配置
  5. Redis和Memcached整体
  6. Nginx反向代理之proxy_pass指令
  7. 众神进入瓦尔哈拉_一时冲动:“通往瓦尔哈拉之路的冒险”
  8. Deepin下java开发环境部署
  9. python实现抢劵_用Python实现微信自动化抢红包,再也不用担心抢不到红包了
  10. 打印出所有的水仙花数javascript_期末C语言特辑 水仙花数
  11. Android开发入门一之Android应用程序架构详解
  12. 卖肾换来一部iPhone后生活不能自理,那手机电商平台现在卖10块钱!
  13. 第一次失效_直击震撼场面!宁乡新沩丰坝建成以来第一次高水位应急演练!
  14. 互联网基础运维分工、职责和技能要求
  15. java 如何将异常_java中的异常处理
  16. O_NONBLOCK与O_NDELAY有何不同?
  17. ks线切割编程系统3.13完整版-2次加密注册码
  18. V4L2视频采集的基本流程
  19. Source must not be null\n\tat org.springframework.util.Assert.notNull(Assert.java:101)
  20. 国内头部高科技企业招聘:大数据方向

热门文章

  1. JS屏蔽某地区(城市)访问网站
  2. 板式家具生产工艺流程是怎样
  3. Python基础教程100天:Day03-分支结构
  4. 儿知错父之过下一句_第034章 子不教,父之过
  5. 法规标准-UN R158标准解读
  6. 电源去耦的原因-和如何电源去耦
  7. 潘伟明:人工智能对人类的特殊价值
  8. mysql查询成绩大于89分_查询每门课程成绩都大于80分学生的姓名
  9. 小程序behaviors使用笔记
  10. 华为上交 | GAN 将古典人像变3D,视角可切换