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 字符过滤类,用于过滤各类用户输入的数据
May 27 PHP
PHP clearstatcache()函数详解
Mar 02 PHP
优化php效率,提高php性能的一些方法
Mar 24 PHP
php设计模式之单例模式使用示例
Jan 20 PHP
PHP异常Parse error: syntax error, unexpected T_VAR错误解决方法
May 06 PHP
浅析ThinkPHP中execute和query方法的区别
Jun 13 PHP
php5.3不能连接mssql数据库的解决方法
Dec 27 PHP
PHP使用内置dir类实现目录遍历删除
Mar 31 PHP
php 把数字转换成汉字的代码
Jul 21 PHP
PHP保存session到memcache服务器的方法
Jan 19 PHP
php实现背景图上添加圆形logo图标的方法
Nov 17 PHP
PHP正则之正向预查与反向预查讲解与实例
Apr 06 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
xml在joomla表单中的应用详解分享
2012/07/19 PHP
YII框架关联查询操作示例
2019/04/29 PHP
基于laravel Request的所有方法详解
2019/09/29 PHP
TP5框架实现一次选择多张图片并预览的方法示例
2020/04/04 PHP
innerText和innerHTML 一些问题分析
2009/05/18 Javascript
qTip2 精致的基于jQuery提示信息插件
2012/02/17 Javascript
给artDialog 5.02 增加ajax get功能详细介绍
2012/11/13 Javascript
js 判断上传文件大小及格式代码
2013/11/13 Javascript
JS导出PDF插件的方法(支持中文、图片使用路径)
2016/07/12 Javascript
浅谈jQuery为哪般去掉了浏览器检测
2016/08/29 Javascript
vue自定义指令directive实例详解
2018/01/17 Javascript
微信小程序实现自定义modal弹窗封装的方法
2018/06/15 Javascript
判断js数据类型的函数实例详解
2019/05/23 Javascript
分享8个JavaScript库可更好地处理本地存储
2020/10/12 Javascript
python爬取网站数据保存使用的方法
2013/11/20 Python
Python学习_几种存取xls/xlsx文件的方法总结
2018/05/03 Python
python 列表转为字典的两个小方法(小结)
2019/06/28 Python
python 类之间的参数传递方式
2019/12/20 Python
Pycharm中配置远程Docker运行环境的教程图解
2020/06/11 Python
pytorch 把图片数据转化成tensor的操作
2021/03/04 Python
可自定义箭头样式的CSS3气泡提示框
2016/03/16 HTML / CSS
英国最大的化装舞会服装网站:Fancydress.com
2017/08/15 全球购物
vue项目实现分页效果
2021/03/24 Vue.js
入党申请人的自我鉴定
2013/12/01 职场文书
医药代表个人的求职信分享
2013/12/08 职场文书
高等教育学自荐书范文
2014/02/10 职场文书
学习雷锋精神心得体会范文
2014/03/12 职场文书
岗位职责说明书模板
2014/07/30 职场文书
六查六看自查报告
2014/10/14 职场文书
2014年环境整治工作总结
2014/12/10 职场文书
高校教师个人总结
2015/02/10 职场文书
调任通知
2015/04/21 职场文书
2015年话务员工作总结
2015/04/29 职场文书
歼十出击观后感
2015/06/11 职场文书
小型企业的绩效考核制度模板
2019/11/21 职场文书
SpringBoot系列之MongoDB Aggregations用法详解
2022/02/12 MongoDB