例文
INSERT INTO details (
denpyo_no,
meisai_id,
item_name
)
VALUES (
:denpyo_no,
:meisai_id,
:item_name
)
ON DUPLICATE KEY UPDATE
item_name = VALUES(item_name);
Laravelで
use Illuminate\Support\Facades\DB;
$sql = "
INSERT INTO users (
id,
name,
email
)
VALUES (
:id,
:name,
:email
)
ON DUPLICATE KEY UPDATE
name = VALUES(name),
email = VALUES(email)
";
DB::statement($sql, [
'id' => 1,
'name' => '田中',
'email' => 'tanaka@example.com',
]);
または、DB::insert() でも実行できます。
DB::insert($sql, [
'id' => 1,
'name' => '田中',
'email' => 'tanaka@example.com',
]);
こちらでもOK。
VALUES() とは何か
この部分が少し分かりにくいかもしれません。
name = VALUES(name)
これは、
「INSERTしようとした name の値を使って更新する」
という意味です。
つまり、次の値を送った場合、
[
'id' => 1,
'name' => '田中',
'email' => 'tanaka@example.com',
]
内部的には次のような処理になります。
- id = 1 が存在しない → INSERT
- id = 1 が存在する → name = '田中', email = 'tanaka@example.com' に更新
重複判定の条件
重複判定には一意制約が必要です。
例えば、主キーなら問題ありません。
PRIMARY KEY (id)
メールアドレスで判定したい場合は、ユニークインデックスを設定します。
UNIQUE KEY uk_email (email)
すると、次のSQLでもUPSERTできます。
INSERT INTO users (email, name)
VALUES (:email, :name)
ON DUPLICATE KEY UPDATE
name = VALUES(name)
複数カラムで判定したい場合
例えば、「会社コード+社員コード」の組み合わせで判定したい場合は、複合ユニークキーを作成します。
ALTER TABLE employee
ADD UNIQUE KEY uk_company_employee (
company_code,
employee_code
);
そのうえで、次のように書きます。
$sql = "
INSERT INTO employee (
company_code,
employee_code,
employee_name
)
VALUES (
:company_code,
:employee_code,
:employee_name
)
ON DUPLICATE KEY UPDATE
employee_name = VALUES(employee_name)
";
DB::statement($sql, [
'company_code' => 'A001',
'employee_code' => 'E100',
'employee_name' => '山田太郎',
]);
なお、VALUES(カラム名) は、MySQL 8.0.20以降では非推奨です。
新しい書き方では、次のようにエイリアスを付けます。
INSERT INTO users (id, name, email)
VALUES (:id, :name, :email) AS new
ON DUPLICATE KEY UPDATE
name = new.name,
email = new.email