栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > PHP

mysql 批量修改

PHP 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

mysql 批量修改

mysql更新语句很简单,更新一条数据的某个字段,一般这样写:

UPDATE mytable SET myfield = ‘value’ WHERe other_field = ‘other_value’;
如果更新同一字段为同一个值,mysql也很简单,修改下
where
即可:

UPDATE mytable SET myfield = ‘value’ WHERe other_field in (‘other_values’);
这里注意,
other_values
是一个逗号

分隔的字符串,如:
1,2,3

那如果是MySQL批量修改不同的记录为不同的值呢?

1 常规方案
那如果修改多条数据为不同的值,可能很多人会这样写:

foreach ($display_order as $id => $ordinal) {
$sql = "UPDATE categories SET display_order = $ordinal WHERe id = i d " ; m y s q l q u e r y ( id"; mysql_query( id";mysqlq​uery(sql);
}
即是循环一条一条的更新记录。

一条记录
update
一次,这样性能很差,也很容易造成阻塞。

2 高效方案
那么能不能一条sql语句实现批量更新呢?

2.1 CASE WHEN
mysql并没有提供直接的方法来实现批量更新,但是可以用点小技巧来实现。

UPDATE mytable SET
myfield = CASE id
WHEN 1 THEN ‘value’
WHEN 2 THEN ‘value’
WHEN 3 THEN ‘value’
END
WHERe id IN (1,2,3)
这里使用了
case when
这个小技巧来实现批量更新。

举个例子:

UPDATE categories SET
display_order = CASE id
WHEN 1 THEN 3
WHEN 2 THEN 4
WHEN 3 THEN 5
END
WHERe id IN (1,2,3)
这句sql的意思是,更新
display_order
字段:

如果
id=1

display_order
的值为
3

如果
id=2

display_order
的值为
4

如果
id=3

display_order
的值为
5

即是将条件语句写在了一起。

这里的
where
部分不影响代码的执行,但是会提高sql执行的效率。

确保sql语句仅执行需要修改的行数,这里只有
3
条数据进行更新,而
where
子句确保只有
3
行数据执行。

3.2 更新多值
如果更新多个值的话,只需要稍加修改:

UPDATE categories SET
display_order = CASE id
WHEN 1 THEN 3
WHEN 2 THEN 4
WHEN 3 THEN 5
END,
title = CASE id
WHEN 1 THEN ‘New Title 1’
WHEN 2 THEN ‘New Title 2’
WHEN 3 THEN ‘New Title 3’
END
WHERe id IN (1,2,3)
到这里,已经完成一条mysql语句更新多条记录了。

但是要在业务中运用,需要结合服务端语言。

3.3 封装成PHP函数
在PHP中,我们把这个功能封装成函数,以后直接调用。

为提高可用性,我们考虑处理更全面的情况。

如下时需要更新的数据,我们要根据
id

parent_id
字段更新
post
表的内容。

其中,
id
的值会变,
parent_id
的值一样。

$data = [
[‘id’ => 1, ‘parent_id’ => 100, ‘title’ => ‘A’, ‘sort’ => 1],
[‘id’ => 2, ‘parent_id’ => 100, ‘title’ => ‘A’, ‘sort’ => 3],
[‘id’ => 3, ‘parent_id’ => 100, ‘title’ => ‘A’, ‘sort’ => 5],
[‘id’ => 4, ‘parent_id’ => 100, ‘title’ => ‘B’, ‘sort’ => 7],
[‘id’ => 5, ‘parent_id’ => 101, ‘title’ => ‘A’, ‘sort’ => 9],
];
例如,我们想让
parent_id

100

title

A
的记录依据不同
id
批量更新:

echo batchUpdate($data, ‘id’, [‘parent_id’ => 100, ‘title’ => ‘A’]);
其中,
batchUpdate()
实现的PHP代码如下:


function batchUpdate($data, $field, KaTeX parse error: Expected '}', got 'EOF' at end of input: … if (!is_array(data) || ! f i e l d ∣ ∣ ! i s a r r a y ( field || !is_array( field∣∣!isa​rray(params)) {
return false;
}

u p d a t e s = p a r s e U p d a t e ( updates = parseUpdate( updates=parseUpdate(data, $field);
w h e r e = p a r s e P a r a m s ( where = parseParams( where=parseParams(params);

// 获取所有键名为 f i e l d 列 的 值 , 值 两 边 加 上 单 引 号 , 保 存 在 field列的值,值两边加上单引号,保存在 field列的值,值两边加上单引号,保存在fields数组中
// array_column()函数需要PHP5.5.0+,如果小于这个版本,可以自己实现,

f i e l d s = a r r a y c o l u m n ( fields = array_column( fields=arrayc​olumn(data, $field);
f i e l d s = i m p l o d e ( ′ , ′ , a r r a y m a p ( f u n c t i o n ( fields = implode(',', array_map(function( fields=implode(′,′,arraym​ap(function(value) {
return “’”.$value."’";
}, $fields));

$sql = sprintf(“UPDATE %s SET %s WHERe %s IN (%s) %s”, ‘post’, $updates, $field, $fields, $where);

return $sql;
}


function parseUpdate($data, $field)
{
$sql = ‘’;
k e y s = a r r a y k e y s ( c u r r e n t ( keys = array_keys(current( keys=arrayk​eys(current(data));
foreach ($keys as $column) {

 $sql .= sprintf("`%s` = CASE `%s` n", $column, $field);
 foreach ($data as $line) {
     $sql .= sprintf("WHEN '%s' THEN '%s' n", $line[$field], $line[$column]);
 }
 $sql .= "END,";

}

return rtrim($sql, ‘,’);
}


function parseParams($params)
{
w h e r e = [ ] ; f o r e a c h ( where = []; foreach ( where=[];foreach(params as $key => $value) {
$where[] = sprintf("%s = ‘%s’", $key, $value);
}

return $where ? ’ AND ’ . implode(’ AND ', $where) : ‘’;
}
得到这样一个批量更新的SQL语句:

UPDATE post SET id = CASE id
WHEN ‘1’ THEN ‘1’
WHEN ‘2’ THEN ‘2’
WHEN ‘3’ THEN ‘3’
WHEN ‘4’ THEN ‘4’
WHEN ‘5’ THEN ‘5’
END,parent_id = CASE id
WHEN ‘1’ THEN ‘100’
WHEN ‘2’ THEN ‘100’
WHEN ‘3’ THEN ‘100’
WHEN ‘4’ THEN ‘100’
WHEN ‘5’ THEN ‘101’
END,title = CASE id
WHEN ‘1’ THEN ‘A’
WHEN ‘2’ THEN ‘A’
WHEN ‘3’ THEN ‘A’
WHEN ‘4’ THEN ‘B’
WHEN ‘5’ THEN ‘A’
END,sort = CASE id
WHEN ‘1’ THEN ‘1’
WHEN ‘2’ THEN ‘3’
WHEN ‘3’ THEN ‘5’
WHEN ‘4’ THEN ‘7’
WHEN ‘5’ THEN ‘9’
END WHERe id IN (‘1’,‘2’,‘3’,‘4’,‘5’) AND parent_id = ‘100’ AND title = ‘A’
生成的SQL把所有的情况都列了出来。

不过因为有
WHERe
限定了条件,所以只有
id

1

2

3
这几条记录被更新。

如果只需要更新某一列,其他条件不限,那么传入的
$data
可以更简单:

d a t a = [ [ ′ i d ′ = > 1 , ′ s o r t ′ = > 1 ] , [ ′ i d ′ = > 2 , ′ s o r t ′ = > 3 ] , [ ′ i d ′ = > 3 , ′ s o r t ′ = > 5 ] , ] ; e c h o b a t c h U p d a t e ( data = [ ['id' => 1, 'sort' => 1], ['id' => 2, 'sort' => 3], ['id' => 3, 'sort' => 5], ]; echo batchUpdate( data=[[′id′=>1,′sort′=>1],[′id′=>2,′sort′=>3],[′id′=>3,′sort′=>5],];echobatchUpdate(data, ‘id’);
这样的数据格式传入,就可以修改
id

1~3
的记录,将
sort
分别改为
1、3、5

得到SQL语句:

UPDATE post SET id = CASE id
WHEN ‘1’ THEN ‘1’
WHEN ‘2’ THEN ‘2’
WHEN ‘3’ THEN ‘3’
END,sort = CASE id
WHEN ‘1’ THEN ‘1’
WHEN ‘2’ THEN ‘3’
WHEN ‘3’ THEN ‘5’
END WHERe id IN (‘1’,‘2’,‘3’)
这种情况更加简单高效。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/268835.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号