电脑疯子技术论坛|电脑极客社区

微信扫一扫 分享朋友圈

已有 1908 人浏览分享

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

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


方法一:

  1. //批量修改 data二维数组 field关键字段 参考ci 批量修改函数 传参方式
  2. function batch_update($table_name='',$data=array(),$field=''){
  3. if(!$table_name||!$data||!$field){
  4. return false;
  5. }else{
  6. $sql='UPDATE '.$table_name;
  7. }
  8. $con=array();
  9. $con_sql=array();
  10. $fields=array();
  11. foreach ($data as $key => $value) {
  12. $x=0;
  13. foreach ($value as $k => $v) {
  14. if($k!=$field&&!$con[$x]&&$x==0){
  15. $con[$x]=" set {$k} = (CASE {$field} ";
  16. }elseif($k!=$field&&!$con[$x]&&$x>0){
  17. $con[$x]=" {$k} = (CASE {$field} ";
  18. }
  19. if($k!=$field){
  20. $temp=$value[$field];
  21. $con_sql[$x].= " WHEN '{$temp}' THEN '{$v}' ";
  22. $x++;
  23. }
  24. }
  25. $temp=$value[$field];
  26. if(!in_array($temp,$fields)){
  27. $fields[]=$temp;
  28. }
  29. }
  30. $num=count($con)-1;
  31. foreach ($con as $key => $value) {
  32. foreach ($con_sql as $k => $v) {
  33. if($k==$key&&$key<$num){
  34. $sql.=$value.$v.' end),';
  35. }elseif($k==$key&&$key==$num){
  36. $sql.=$value.$v.' end)';
  37. }
  38. }
  39. }
  40. $str=implode(',',$fields);
  41. $sql.=" where {$field} in({$str})";
  42. $res=M($table_name)->execute($sql);
  43. return $res;
  44. }
  45. //测试
  46. function test(){
  47. $update_array=array();
  48. for ($i=2; $i <7 ; $i++) {
  49. $data=array();
  50. $data['id']=$i;
  51. $data['memeber_type']=2;
  52. $data['memeber_type_state']=1;
  53. $update_array[]=$data;
  54. }
  55. $res=$this->batch_update('yl_member',$update_array,id);
  56. var_dump($res);
  57. }
复制代码


方法二:

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

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


  1. UPDATE categories
  2. SET display_order = CASE id
  3. WHEN 1 THEN 3
  4. WHEN 2 THEN 4
  5. WHEN 3 THEN 5
  6. END
  7. 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行数据执行。

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


  1. UPDATE categories
  2. SET display_order = CASE id
  3. WHEN 1 THEN 3
  4. WHEN 2 THEN 4
  5. WHEN 3 THEN 5
  6. END,
  7. title = CASE id
  8. WHEN 1 THEN 'New Title 1'
  9. WHEN 2 THEN 'New Title 2'
  10. WHEN 3 THEN 'New Title 3'
  11. END
  12. WHERE id IN (1,2,3)
复制代码


实际运用

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

复制代码


方法二不建议使用。

方法三:


  1. /*
  2. * @param $saveWhere :想要更新主键ID数组
  3. * @param $saveData :想要更新的ID数组所对应的数据
  4. * @param $tableName : 想要更新的表明
  5. * @param $saveWhere : 返回更新成功后的主键ID数组
  6. * */
  7. public function saveAll($saveWhere,&$saveData,$tableName){
  8. if($saveWhere==null||$tableName==null)
  9. return false;
  10. //获取更新的主键id名称
  11. $key = array_keys($saveWhere)[0];
  12. //获取更新列表的长度
  13. $len = count($saveWhere[$key]);
  14. $flag=true;
  15. $model = isset($model)?$model:M($tableName);
  16. //开启事务处理机制
  17. $model->startTrans();
  18. //记录更新失败ID
  19. $error=[];
  20. for($i=0;$i<$len;$i++){
  21. //预处理sql语句
  22. $isRight=$model->where($key.'='.$saveWhere[$key][$i])->save($saveData[$i]);
  23. if($isRight==0){
  24. //将更新失败的记录下来
  25. $error[]=$i;
  26. $flag=false;
  27. }
  28. //$flag=$flag&&$isRight;
  29. }
  30. if($flag ){
  31. //如果都成立就提交
  32. $model->commit();
  33. return $saveWhere;
  34. }elseif(count($error)>0&count($error)<$len){
  35. //先将原先的预处理进行回滚
  36. $model->rollback();
  37. for($i=0;$i<count($error);$i++){
  38. //删除更新失败的ID和Data
  39. unset($saveWhere[$key][$error[$i]]);
  40. unset($saveData[$error[$i]]);
  41. }
  42. //重新将数组下标进行排序
  43. $saveWhere[$key]=array_merge($saveWhere[$key]);
  44. $saveData=array_merge($saveData);
  45. //进行第二次递归更新
  46. $this->saveAll($saveWhere,$saveData,$tableName);
  47. return $saveWhere;
  48. }
  49. else{
  50. //如果都更新就回滚
  51. $model->rollback();
  52. return false;
  53. }
  54. }

复制代码



在测试方法中调用:


  1. public function test(){
  2. //要更新的数据表的主键数组
  3. $where['ID']=array(70,73,74,80,83);
  4. //ID主键数组对应的待更新数据
  5. $save=array(
  6. array('School'=>'DK Univisity01','isExport'=>0),
  7. array('School'=>'DK Univisity02','isExport'=>0),
  8. array('School'=>'DK Univisity03','isExport'=>0),
  9. array('School'=>'DK Univisity04','isExport'=>0),
  10. array('School'=>'','isExport'=>0),
  11. // array('School'=>' Univisity05','isExport'=>0),
  12. );
  13. $f=$this->saveAll($where,$save,'want');
  14. if(count($f['ID'])>0){
  15. //返回更新成功的ID数组
  16. echo "This is success :</br>";
  17. dump($f);
  18. echo 'ok';
  19. }else{
  20. //更新失败操作
  21. echo "This is failed :</br>";
  22. dump($f);
  23. echo 'error';
  24. }
  25. }
复制代码


以上所述是小编给大家介绍的Thinkphp批量更新数据的方法汇总,希望对大家有所帮助,

如果大家有任何疑问请给我留言,小编会及时回复大家的。

在此也非常感谢大家对电脑疯子的支持!






您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

关注

0

粉丝

9021

主题
精彩推荐
热门资讯
网友晒图
图文推荐

Powered by Pcgho! X3.4

© 2008-2022 Pcgho Inc.