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中突破基于HTTP_REFERER的防盗链措施(stream_context_create)
Mar 29 PHP
将博客园(cnblogs.com)数据导入到wordpress的代码
Jan 06 PHP
php图片加水印原理(超简单的实例代码)
Jan 18 PHP
php实现cc攻击防御和防止快速刷新页面示例
Feb 13 PHP
PHP中使用glob函数实现一句话删除某个目录下的所有文件
Jul 22 PHP
php修改文件上传限制方法汇总
Apr 07 PHP
老版本PHP转义Json里的特殊字符的函数
Jun 08 PHP
详解PHP对数组的定义以及数组的创建方法
Nov 27 PHP
PHP实现的简单分页类及用法示例
May 06 PHP
PHP封装的MSSql操作类完整实例
May 26 PHP
PHP中call_user_func_array回调函数的用法示例
Nov 26 PHP
Laravel如何使用Redis共享Session
Feb 23 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
浅谈php serialize()与unserialize()的用法
2013/06/05 PHP
php如何解决无法上传大于8M的文件问题
2014/03/10 PHP
php实现URL加密解密的方法
2016/11/17 PHP
关于Laravel Route重定向的一个注意点
2017/01/16 PHP
PHP进程通信基础之信号量与共享内存通信
2017/02/19 PHP
php让json_encode不自动转义斜杠“/”的方法
2020/04/27 PHP
jquery HotKeys轻松搞定键盘事件代码
2008/08/30 Javascript
jquery动态改变div宽度和高度
2015/02/09 Javascript
理解Javascript文件动态加载
2016/01/29 Javascript
Bootstrap时间选择器datetimepicker和daterangepicker使用实例解析
2016/09/17 Javascript
JS判断来路是否是百度等搜索索引进行弹窗或自动跳转的实现代码
2016/10/09 Javascript
Vue.js中数据绑定的语法教程
2017/06/02 Javascript
微信小程序中页面FOR循环和嵌套循环
2017/06/21 Javascript
10个在JavaScript开发中常遇到的BUG
2017/12/18 Javascript
详解如何用webpack4从零开始构建react开发环境
2019/01/27 Javascript
原生JS实现贪吃蛇小游戏
2020/03/09 Javascript
基于PHP pthreads实现多线程代码实例
2020/06/24 Javascript
vue前端和Django后端如何查询一定时间段内的数据
2021/02/28 Vue.js
采用python实现简单QQ单用户机器人的方法
2014/07/03 Python
python调用新浪微博API项目实践
2014/07/28 Python
使用Python的Zato发送AMQP消息的教程
2015/04/16 Python
python遍历序列enumerate函数浅析
2017/10/17 Python
Python3 安装PyQt5及exe打包图文教程
2019/01/08 Python
Python read函数按字节(字符)读取文件的实现
2019/07/03 Python
python判断元素是否存在的实例方法
2020/09/24 Python
Html5中localStorage存储JSON数据并读取JSON数据的实现方法
2017/02/13 HTML / CSS
adidas官方旗舰店:德国运动用品制造商
2017/11/25 全球购物
英国工作场所设备购买网站:Slingsby
2019/05/03 全球购物
Woods官网:加拿大最古老、最受尊敬的户外品牌之一
2020/09/12 全球购物
杭州-飞时达软件有限公司.net笔面试
2012/04/28 面试题
企业文明单位申报材料
2014/05/16 职场文书
自主招生学校推荐信
2014/09/26 职场文书
华山导游词
2015/02/03 职场文书
创业计划书之密室逃脱
2019/11/08 职场文书
三十年再续同学情倡议书
2019/11/27 职场文书
在python中读取和写入CSV文件详情
2022/06/28 Python