Thinkphp批量更新数据的方法汇总


Posted in PHP onJune 29, 2016

以下小编给大家列出了三种实现thinkphp批量更新数据的方法,写的不好还请见谅,有意见欢迎提出,共同学习进步!

方法一:

//批量修改 data二维数组 field关键字段 参考ci 批量修改函数 传参方式
function batch_update($table_name='',$data=array(),$field=''){
if(!$table_name||!$data||!$field){
return false;
}else{
$sql='UPDATE '.$table_name;
}
$con=array();
$con_sql=array();
$fields=array();
foreach ($data as $key => $value) {
$x=0;
foreach ($value as $k => $v) {
if($k!=$field&&!$con[$x]&&$x==0){
$con[$x]=" set {$k} = (CASE {$field} ";
}elseif($k!=$field&&!$con[$x]&&$x>0){
$con[$x]=" {$k} = (CASE {$field} ";
}
if($k!=$field){
$temp=$value[$field];
$con_sql[$x].= " WHEN '{$temp}' THEN '{$v}' ";
$x++;
}
}
$temp=$value[$field];
if(!in_array($temp,$fields)){
$fields[]=$temp;
} 
}
$num=count($con)-1;
foreach ($con as $key => $value) {
foreach ($con_sql as $k => $v) {
if($k==$key&&$key<$num){
$sql.=$value.$v.' end),';
}elseif($k==$key&&$key==$num){
$sql.=$value.$v.' end)';
}
}
}
$str=implode(',',$fields);
$sql.=" where {$field} in({$str})";
$res=M($table_name)->execute($sql);
return $res;
}
//测试
function test(){
$update_array=array();
for ($i=2; $i <7 ; $i++) { 
$data=array();
$data['id']=$i;
$data['memeber_type']=2;
$data['memeber_type_state']=1;
$update_array[]=$data;
}
$res=$this->batch_update('yl_member',$update_array,id);
var_dump($res);
}

方法二:

即是循环一条一条的更新记录。一条记录update一次,这样性能很差,也很容易造成阻塞。

那么能不能一条sql语句实现批量更新呢?mysql并没有提供直接的方法来实现批量更新,但是可以用点小技巧来实现。

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行数据执行。

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

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)

实际运用

$display_order = array( 
1 => 4, 
2 => 1, 
3 => 2, 
4 => 3, 
5 => 9, 
6 => 5, 
7 => 8, 
8 => 9 
); 
$ids = implode(',', array_keys($display_order)); 
$sql = "UPDATE categories SET display_order = CASE id "; 
foreach ($display_order as $id => $ordinal) { 
$sql .= sprintf("WHEN %d THEN %d ", $id, $ordinal); 
} 
$sql .= "END WHERE id IN ($ids)"; 
echo $sql;

方法二不建议使用。

方法三:

/*
* @param $saveWhere :想要更新主键ID数组
* @param $saveData :想要更新的ID数组所对应的数据
* @param $tableName : 想要更新的表明
* @param $saveWhere : 返回更新成功后的主键ID数组
* */
public function saveAll($saveWhere,&$saveData,$tableName){
if($saveWhere==null||$tableName==null)
return false;
//获取更新的主键id名称
$key = array_keys($saveWhere)[0];
//获取更新列表的长度
$len = count($saveWhere[$key]);
$flag=true;
$model = isset($model)?$model:M($tableName);
//开启事务处理机制
$model->startTrans();
//记录更新失败ID
$error=[];
for($i=0;$i<$len;$i++){
//预处理sql语句
$isRight=$model->where($key.'='.$saveWhere[$key][$i])->save($saveData[$i]);
if($isRight==0){
//将更新失败的记录下来
$error[]=$i;
$flag=false;
}
//$flag=$flag&&$isRight;
}
if($flag ){
//如果都成立就提交
$model->commit();
return $saveWhere;
}elseif(count($error)>0&count($error)<$len){
//先将原先的预处理进行回滚
$model->rollback();
for($i=0;$i<count($error);$i++){
//删除更新失败的ID和Data
unset($saveWhere[$key][$error[$i]]);
unset($saveData[$error[$i]]);
}
//重新将数组下标进行排序
$saveWhere[$key]=array_merge($saveWhere[$key]);
$saveData=array_merge($saveData);
//进行第二次递归更新
$this->saveAll($saveWhere,$saveData,$tableName);
return $saveWhere;
}
else{
//如果都更新就回滚
$model->rollback();
return false;
}
}

在测试方法中调用:

public function test(){
//要更新的数据表的主键数组
$where['ID']=array(70,73,74,80,83);
//ID主键数组对应的待更新数据
$save=array(
array('School'=>'DK Univisity01','isExport'=>0),
array('School'=>'DK Univisity02','isExport'=>0),
array('School'=>'DK Univisity03','isExport'=>0),
array('School'=>'DK Univisity04','isExport'=>0),
array('School'=>'','isExport'=>0),
// array('School'=>' Univisity05','isExport'=>0),
);
$f=$this->saveAll($where,$save,'want');
if(count($f['ID'])>0){
//返回更新成功的ID数组
echo "This is success :</br>";
dump($f);
echo 'ok';
}else{
//更新失败操作
echo "This is failed :</br>";
dump($f);
echo 'error';
}
}

以上所述是小编给大家介绍的Thinkphp批量更新数据的方法汇总,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

PHP 相关文章推荐
php 设计模式之 单例模式
Dec 19 PHP
php读取xml实例代码
Jan 28 PHP
php ftp文件上传函数(基础版)
Jun 03 PHP
php产生随机数的两种方法实例代码 输出随机IP
Apr 08 PHP
thinkphp中连接oracle时封装方法无法用的解决办法
Jun 17 PHP
免费手机号码归属地API查询接口和PHP使用实例分享
Apr 10 PHP
浅谈php正则表达式中的非贪婪模式匹配的使用
Nov 25 PHP
php项目开发中用到的快速排序算法分析
Jun 25 PHP
php实现数据库的增删改查
Feb 26 PHP
PHP+Apache环境中如何隐藏Apache版本
Nov 24 PHP
php判断电子邮件是否正确方法
Dec 04 PHP
PHP Ajax跨域问题解决方案代码实例
Aug 01 PHP
ThinkPHP实现更新数据实例详解(demo)
Jun 29 #PHP
php结合mysql与mysqli扩展处理事务的方法
Jun 29 #PHP
php简单解析mysqli查询结果的方法(2种方法)
Jun 29 #PHP
php mysqli查询语句返回值类型实例分析
Jun 29 #PHP
thinkphp框架实现数据添加和显示功能
Jun 29 #PHP
thinkphp框架实现删除和批量删除
Jun 29 #PHP
浅谈PHP值mysql操作类
Jun 29 #PHP
You might like
解密ThinkPHP3.1.2版本之模块和操作映射
2014/06/19 PHP
PHP实现上传文件并存进数据库的方法
2015/07/16 PHP
网页的分页下标生成代码(PHP后端方法)
2016/02/03 PHP
PHP获取当前日期及本周一是几月几号的方法
2017/03/28 PHP
理清PHP在Linxu下执行时的文件权限方法
2017/06/07 PHP
PHP登录验证功能示例【用户名、密码、验证码、数据库、已登陆验证、自动登录和注销登录等】
2019/02/25 PHP
php将字符串转换为数组实例讲解
2020/05/05 PHP
js前台分页显示后端JAVA数据响应
2013/03/18 Javascript
JS+CSS 制作的超级简单的下拉菜单附图
2013/11/22 Javascript
让图片跳跃起来  javascript图片轮播特效
2016/02/16 Javascript
分享12个非常实用的JavaScript小技巧
2016/05/11 Javascript
JQuery点击事件回到页面顶部效果的实现代码
2016/05/24 Javascript
详解Angular2中的编程对象Observable
2016/09/17 Javascript
原生Javascript和jQuery做轮播图简单例子
2016/10/11 Javascript
实现隔行换色效果的两种方式【实用】
2016/11/27 Javascript
使用vue和datatables进行表格的服务器端分页实例代码
2017/06/07 Javascript
深入讲解xhr(XMLHttpRequest)/jsonp请求之abort
2017/07/26 Javascript
详解angular脏检查原理及伪代码实现
2018/06/08 Javascript
关于AOP在JS中的实现与应用详解
2019/05/06 Javascript
Vue CLI3中使用compass normalize的方法
2019/05/30 Javascript
jQuery实现的移动端图片缩放功能组件示例
2020/05/01 jQuery
vue pages 多入口项目 + chainWebpack 全局引用缩写说明
2020/09/21 Javascript
Python实现发送email的几种常用方法
2014/08/18 Python
发布你的Python模块详解
2016/09/15 Python
Python基于sklearn库的分类算法简单应用示例
2018/07/09 Python
Python进阶:生成器 懒人版本的迭代器详解
2019/06/29 Python
Python基于pyjnius库实现访问java类
2020/07/31 Python
基于Python的图像阈值化分割(迭代法)
2020/11/20 Python
详解修改Anaconda中的Jupyter Notebook默认工作路径的三种方式
2021/01/24 Python
网络技术专业推荐信
2014/02/20 职场文书
典型事迹材料范文
2014/12/29 职场文书
资料员岗位职责范本
2015/04/13 职场文书
高考1977观后感
2015/06/04 职场文书
浅析InnoDB索引结构
2021/04/05 MySQL
【TED出品】天梯非主流开心游1700 划水骑士
2022/03/31 魔兽争霸
【海涛教你打DOTA】黑鸟第一视角解说
2022/04/01 DOTA