简体   繁体   English

Laravel 批量更新多个记录 ID

[英]Laravel Bulk Update for multiple record ids

I want to mass update my records in Laravel but the records not getting updated.我想在 Laravel 中批量更新我的记录,但记录没有得到更新。 I have a different record for each Id.我对每个 ID 都有不同的记录。 Below is what I am trying.下面是我正在尝试的。

$ids = [5,6,8,9],
$updated_array = [
  ['name' => 'tarun'],
  ['name' => 'Akash'],
  ['name' => 'Soniya'],
  ['name' => 'Shalu'],
];

Model::whereIn('id', $ids)->update($updated_array);

Mass updates are used when you're trying to update multiple rows to the same values.当您尝试将多行更新为相同的值时,会使用批量更新。 You cannot mass update with different values.您不能使用不同的值进行批量更新。

Therefore, this would work, but would update all matching records to name of 'tarun':因此,这会起作用,但会将所有匹配的记录更新为“tarun”的名称:

Model::whereIn('id', $ids)->update(['name' => 'tarun']);

For your example, you could do:对于您的示例,您可以执行以下操作:

foreach($ids as $key => $id) {
    Model::where('id', $id)->update($updated_array[$key]);
}

But as far as I know, there's no way to do this without running 4 queries in Laravel and writing a raw SQL statement to accomplish this would even be messy.但据我所知,如果没有在 Laravel 中运行 4 个查询并编写原始 SQL 语句来完成此操作,则无法做到这一点甚至会很混乱。

Some good solutions for this issue are on the following post: https://github.com/laravel/ideas/issues/575这个问题的一些好的解决方案在以下帖子中: https : //github.com/laravel/ideas/issues/575

1) Can create custom function to do this, which uses raw SQL, as per barryvdh comment in the post. 1) 可以创建自定义函数来执行此操作,该函数使用原始 SQL,根据帖子中的 barryvdh 评论。

    public static function updateValues(array $values)
    {
        $table = MyModel::getModel()->getTable();

        $cases = [];
        $ids = [];
        $params = [];

        foreach ($values as $id => $value) {
            $id = (int) $id;
            $cases[] = "WHEN {$id} then ?";
            $params[] = $value;
            $ids[] = $id;
        }

        $ids = implode(',', $ids);
        $cases = implode(' ', $cases);
        $params[] = Carbon::now();

        return \DB::update("UPDATE `{$table}` SET `value` = CASE `id` {$cases} END, `updated_at` = ? WHERE `id` in ({$ids})", $params);
    }

This apparently increase performance by 13x这显然将性能提高了 13 倍

2) As per another comment, another idea is to do it on a per record basis, but do the whole thing as a single transaction, which makes it much faster. 2)根据另一条评论,另一个想法是在每条记录的基础上进行,但将整个操作作为单个事务进行,这使其速度更快。

    DB::beginTransaction();

    // your loop and updates;

    if( !$user )
    {
    rollbackTransaction();
    } else {
    // Else commit the queries
    commitTransaction();
    }


3) There is a laravel library also that appears to try and solve this issue. 3) 还有一个 laravel 库似乎试图解决这个问题。 https://github.com/mavinoo/laravelBatch https://github.com/mavinoo/laravelBatch

Note: I have not tried or tested any of the above solutions.注意:我没有尝试或测试上述任何解决方案。

I think the only way to do this without n queries would be to我认为没有 n 查询的唯一方法是

  • (optional) backup table (可选)备份表
  • grab the records and create an array with all the updated data获取记录并创建一个包含所有更新数据的数组
  • bulk delete the records批量删除记录
  • bulk insert from array从数组批量插入

That's 3 queries.这是3个查询。

Iterating through n records is not practical for my application either;遍历 n 条记录对我的应用程序也不实用; I was hoping there was an alternative but it looks like I'm going to have to implement this.我希望有一个替代方案,但看起来我将不得不实施这一点。

Please try the below code:请尝试以下代码:

$data_to_be_updated = [ ['id'=>5,'name' => 'tarun'], ['id'=>6, 'name' => 'Akash'],
                        ['id'=>8, 'name' => 'Soniya'], ['id'=>9,'name' => 'Shalu']
                      ];
foreach ($data_to_be_updated as $key => $value) {
    $data = Model::where('id',$value['id'])->first();
    if ($data) {
        $data->name = $value['name'];
        $data->save();
    }
}

请尝试下面给出的以下代码进行批量更新

 <ModelName>::where('id', $id)->update($request->all());

We can Insert and update batch (bulk) in laravel using this Package我们可以使用这个包在 laravel 中插入和更新批处理(批量)

You can use Laravel Upsert for mass update.您可以使用Laravel Upsert进行批量更新。 For example:例如:

User::query()->upsert([
    ['id' => 1, 'email' => 'dadan@example.com'],
    ['id' => 2, 'email' => 'satria@example.com'],
], 'email');

This feature available in Laravel 8 or newer此功能在 Laravel 8 或更新版本中可用

you can do it like this above mentioned:-你可以像上面提到的那样做:-

foreach($ids as $key => $id) {
    Model::where('id', $id)->update($updated_array[$key]);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM