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 は提示した値であり、修飾なしの列名は既に保存されて
いる値です。
例
- これが避ける衝突
rating_count は rating を主キーとして持ちます。行を書き込みます。
- 挿入するか、邪魔になっているものを更新する
2 rows affected と言います。この数は、
文がどちらの分岐を取ったかを伝える方法です。行を挿入したら 1、行を更新したら
2、更新が値を既に正しいと判断したら 0 です。
- 存在しない行に対する同じ文
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、およびどれを使うか