2019-07-15 18:34:50 3853次浏览 7条回答 1 悬赏 10 金钱

批量插入有 batchInsert 方法,那么批量更新为什么没有 batchUpdate 方法呢?
遇到需要批量更新多字段的情况,大佬们都是怎么做的,求指导

最佳答案

  • 发布于 2019-07-16 11:16 举报

    你只要把 拼接sql 封装到一个函数中,不就可以像 batchInsert 那样 “优雅”的调用了么
    其实 yii 的 batchInsert 一样是 拼接sql,可以找下它的源码看看,同时 可以做为参考,写出你自己的 batchUpdate

  • 回答于 2019-07-15 19:17 举报

    你说的批量更新是什么?
    比如同时更新id=3,4,5的记录,将状态改为禁用,这是一种批量更新,可以用一条sql更新;
    比如同时更新id=3,4,5的记录,要求3的状态为禁用,4,5的状态为启用,这种需要肯定不能用一条sql更新;

    1 条回复
    回复于 2019-07-15 19:40 回复

    类似这种:

    update table set value1=value11,value2=value21 where id=1;
    update table set value1=value12,value2=value22 where id=2;
    update table set value1=value13,value2=value23 where id=3;
    update table set value1=value14,value2=value24 where id=4;
    

    value1 和 value2 字段的值 每条更新记录值都不一样

  • 回答于 2019-07-15 20:05 举报

    可以用 case when :

    update table set
        value1 = case id
            when 1 then value11
            when 2 then value12
            when 3 then value13
            when 4 then value14
        end,
        value2 = case id
            when 1 then value21
            when 2 then value22
            when 3 then value23
            when 4 then value24
        end
    where id in (1,2,3,4)
    
    1 条回复
    回复于 2019-07-15 20:13 回复

    还是只能拼写SQL么,没有batchInsert那么优雅的方法

  • 回答于 2019-07-16 09:30 举报

    一般实现的也就是foreach + 事务

  • 回答于 2019-07-16 09:31 举报

    tp 等一些框架都是这么实现的

  • 回答于 2019-07-16 09:49 举报

    看到很多人对于 类似批量更新 提出的问题,另外据个人所知框架是没有提供什么优雅便捷方法的 (也欢迎大牛补充)。
    这边先说下拼接 SQL 的样例:

    public function logicFun()
    {
        $tbName = 'tb_test';
        $db = \Yii::$app->getDb();
        $sqls = [];
        $sqls[] = (new \yii\db\Query())->createCommand($db)
            ->update($tbName,['lock'=>'yes'],['id'=>3])
            ->getRawSql();
        $sqls[] = (new \yii\db\Query())->createCommand($db)
            ->update($tbName,['lock'=>'no'],['id'=>[4,5]])
            ->getRawSql();
        $sql = implode(";\n", $sqls) . ';';
        $query = $db->createCommand($sql);
    
    //        var_dump($query->getRawSql());
    //output:
    //        UPDATE `tb_test` SET `lock`='yes' WHERE `id`=3;
    //        UPDATE `tb_test` SET `lock`='no' WHERE `id` IN (4, 5);
    
        return $query->execute();
    }
    

    看一下上述代码,或许大家会觉得,“我要找的是优雅的解决方法,这么麻烦的话,我还用得着这样写?!” 还不如直接更新呢,如下:

    ModelClass::updateAll(['lock'=>'yes'],['id'=>3]);
    ModelClass::updateAll(['lock'=>'no'],['id'=>[4,5]]);
    

    说实话 ,“从(拼接)SQL中寻找优雅的解决方案” 个人是不太能理解的,因为更新跟批量插入本就是不同的场景。 或者说批量插入,也是提前准备好的数据,而不是在sql中决定具体插入的字段值。
    自认为把数据处理逻辑写到sql中会让代码逻辑更加晦涩,后期维护难度更高。
    所以,“非得一次拼接出 批量更新的语句” 或者 “非常优雅的解决一些高复杂的问题”,个人觉得可以追求 但不必苛求。
    个人观点,欢迎补充,不喜勿喷。

  • 回答于 2019-09-16 18:17 举报

    仅供参考:
    $ids = '1,2,3,4,5,';
    $rtn = Orders::updateAll([

    'status'     => 1,
    'updated_at' => time(),
    

    ], 'id IN('.substr($ids, 0, -1).')');

您需要登录后才可以回答。登录 | 立即注册
codetu
试用期

codetu 北京

注册时间:2013-11-17
最后登录:2019-08-30
在线时长:1小时43分
  • 粉丝0
  • 金钱15
  • 威望0
  • 积分25

热门问题