メインコンテンツへスキップ

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples on this page work on VillageSQL. Install Now →
行があるかどうか分からないことがあります。INSERT ... ON DUPLICATE KEY UPDATE は、行がなければ書き込み、あれば変更します。1 つの文で、事前の確認なしにです。 これは、あらゆる「この設定を保存する」と、増やす前に作成しなければならない あらゆるカウンターの背後にある文です。 これらの例は、INSERT の sakila_practice データベースを 使います。始める前にそこにあるセットアップのブロックをもう一度実行し、次に mysql -u root -p sakila_practice でクライアントを開いてください。

仕組み

TABLE_NAME をテーブルに、COLUMN_LIST と VALUE_LIST を通常の挿入と同じ 列と値に、ROW_ALIAS を提示する行の名前に、COLUMN_NAME を行が既にあるときに 変更する列に置き換えます。 ON DUPLICATE KEY UPDATE 句は、挿入が PRIMARY KEY または UNIQUE インデックス に違反する場合にだけ実行されます。エイリアスは挿入しようとした行の名前なので、 ROW_ALIAS.COLUMN_NAME は提示した値であり、修飾なしの列名は既に保存されて いる値です。

例

  1. これが避ける衝突

rating_count は rating を主キーとして持ちます。行を書き込みます。
新しい件数でもう一度書き込むと、挿入は失敗します。

  1. 挿入するか、邪魔になっているものを更新する

保存されている行は 1 つなのに、文は 2 rows affected と言います。この数は、 文がどちらの分岐を取ったかを伝える方法です。行を挿入したら 1、行を更新したら 2、更新が値を既に正しいと判断したら 0 です。
行は見つかり、既に 179 を保持していたため、書き込むものはありませんでした。 影響を受けた行数を、テーブル内の行数として読んではいけません。

  1. 存在しない行に対する同じ文

1 row affected は挿入の分岐です。文について変わったのは値だけで、それが この文の要点です。呼び出し側は行があるかどうかを知る必要がありません。

集計全体を更新する

行はクエリから来ることもでき、それが集計テーブルを 1 つの文で最新にする方法 です。そこではエイリアス形式は許可されません。
代わりに、クエリを派生テーブルで包んでクエリ 自体にエイリアスを与え、提示する値をそこから読みます。
Duplicates: 1 は G の行で、179 として保存されていたものが今は 178 です。 3 つの新しいレーティングが、影響を受けた 5 行のうち 3 行を占め、その 1 つの 更新が残りの 2 行を占めます。R は既に 195 を保持していたため、まったく 数えられていません。

古いコードはエイリアスの代わりに VALUES() を使う

古い文は、提示された値をエイリアスの代わりに VALUES(films) で読みます。 その形式はまだ動作しますが、警告を出します。
\G はセミコロンと同じように文を終え、1 行に 1 列ずつ表示します。これは、 表には幅が広すぎるメッセージを読む方法です。新しい文はエイリアスで書き、以前に 書かれたコードでは VALUES() に出会うと考えてください。

まとめ

  • 行があるかもしれないしないかもしれないときは INSERT ... ON DUPLICATE KEY UPDATE を使います。
  • この句は PRIMARY KEY または UNIQUE の衝突のときにだけ実行されると考えてください。
  • 影響を受けた行数は、挿入なら 1、更新なら 2、変更なしなら 0 として読みます。
  • 提示する行に AS alias で名前を付け、その値を alias.column として読みます。
  • 行が SELECT から来るときは、クエリを派生テーブルで包みます。
  • VALUES(col) をエイリアス形式に置き換えます。それが警告 1287 の求めるものです。

関連項目

  • INSERT — 基本の形と ERROR 1062
  • INSERT SELECT — クエリからの行
  • UPDATE — あると分かっている行の変更
  • MySQL の UPSERT — REPLACE、INSERT IGNORE、およびどれを使うか