0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

UPSERT

0
Posted at

例文

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
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?