LoginSignup
14
6

More than 1 year has passed since last update.

Laravelで気軽にバルクアップデートしたい

Posted at

バルクアップデートとは

バッチ処理などでは、データベースに複数の行を挿入したり、更新したりしたい場合がよくあると思います。挿入に関しては、大抵のRDBMSではINSERT INTO table (...) VALUES (...), (...)のような形で簡単に実行可能ですし、Laravelでもinsert()の第1引数に連想配列の配列を渡せば可能です。

更新に関してはそう簡単ではありませんが、MySQLに限っては、ELT()FIELD()という2つの関数を使った方法で可能です。ただし、これをLaravelで実行するのはだいぶややこしいので、簡単に実行できるようにしてみました。

使い方

上記にあるサービスプロバイダクラスのファイルを、app/Providers以下に配置し、config/app.phpprovidersApp\Providers\MySqlBulkUpdateServiceProvider::classを追加、その上で、

<?php

DB::table('users')->whereNull('email_verified_at')->updateBulk([
    ['id' => 1, 'name' => 'admin1', 'email' => 'admin@example.com'],
    ['id' => 2, 'name' => 'admin2', 'email' => 'admin@example.com'],
    ['id' => 3, 'name' => 'admin3', 'email' => 'admin@example.com'],
]);

あるいは、

<?php

App\Models\User::whereNull('email_verified_at')->updateBulk([
    ['id' => 1, 'name' => 'admin1', 'email' => 'admin@example.com'],
    ['id' => 2, 'name' => 'admin2', 'email' => 'admin@example.com'],
    ['id' => 3, 'name' => 'admin3', 'email' => 'admin@example.com'],
]);

のように実行します。

詳細

第1引数で渡した配列から、id(Eloquent\Builderからの場合は、モデルに設定された主キー)あるいは第2引数で渡したカラムで検索し、残りの値を更新します。上記のQuery\Builderの例の場合は、以下のようなSQLにコンパイルされます。

UPDATE
    `users`
SET
    `name` = ELT(FIELD(`id`, ?, ?, ?), ?, ?, ?),
    `email` = ?
WHERE
    `email_verified_at` IS NULL
    AND `id` IN (?, ?, ?)

emailは全行で同じとなっているため、ELT(), FIELD()は使わない形にします。また、updateBulk()以前に追加したWHERE句も別途設定されます。

さらに、Eloquent\Builder経由の場合はupdated_at等も自動で設定されます。

Query\Builder経由の実行時に、主キーがid以外の場合、あるいはEloquent\Builderで、主キー以外で検索したい場合は、第2引数にカラム名を指定します。

DB::table('users')->updateBulk([
    ['name' => 'admin1', 'email' => 'admin1@example.com'],
    ['name' => 'admin2', 'email' => 'admin2@example.com'],
    ['name' => 'admin3', 'email' => 'admin3@example.com'],
], 'email');

この記事のライセンス

クリエイティブ・コモンズ・ライセンス
この文書はCC BY(クリエイティブ・コモンズ表示4.0国際ライセンス)で公開します。

14
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
6