もし ON DUPLICATE KEY UPDATE
を指定し、UNIQUE
インデックスか
PRIMARY KEY
内で複製値を引き起こす行が挿入されると、古い行の
UPDATE
が実行されます。例えば、もしカラム
a
が UNIQUE
として宣言され、それが値 1
を含んでいたら、次の2つのステートメントは同一効果を持ちます。
INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1; UPDATE table SET c=c+1 WHERE a=1;
もしその行が新しいレコードとして挿入されると、行に影響される値は1となり、もし既存レコードが更新されると2になります。
もしカラム b
も固有であれば、INSERT
は代わりにこの UPDATE
ステートメントと同等になります。
UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;
もし a=1 OR b=2
がいくつかの行とマッチすれば、1つの
行だけが更新されます。通常、複数の固有インデックスを持つテーブル上で
ON DUPLICATE KEY
条項を利用するのは避けるべきです。
INSERT ... UPDATE
ステートメントの
INSERT
部分からカラム値を参照する為に、UPDATE
条項の中で
VALUES(
関数を利用する事ができます。言い換えると、col_name
)UPDATE
条項の中の
VALUES(
は、挿入される col_name
)col_name
の値を参照し、複製キーの矛盾は起きないという事です。この関数は、時に複合行挿入をする時に有効です。VALUES()
関数は、INSERT ... UPDATE
ステートメントの中でだけ意味を持ち、そうでなければ
NULL
を返します。例:
INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6) ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
そのステートメントは次の2つと同一です。
INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=3; INSERT INTO table (a,b,c) VALUES (4,5,6) ON DUPLICATE KEY UPDATE c=9;
もしテーブルが AUTO_INCREMENT
カラムを含み INSERT ... UPDATE
が行を挿入すると、LAST_INSERT_ID()
関数は AUTO_INCREMENT
値を返します。もしステートメントが代わりに行を更新すると、LAST_INSERT_ID()
は無意味になります。しかし、LAST_INSERT_ID(
を利用する事でこれに対処する事ができます。expr
)id
が AUTO_INCREMENT
カラムだと仮定してください。LAST_INSERT_ID()
が更新に意味を持つようにするには、次のように行を挿入してください。
INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;
ON DUPLICATE KEY UPDATE
を利用する時は DELAYED
オプションは無視されます。