データベースにデータを登録する際に、INSERT と UPDATE か判断して実行しなければならないことがある。たとえば、カテゴリーの追加と更新を行うページで、ID が付与されている場合は ID をキーにして UPDATE、されていなければ INSERT を行うようなケースだ。MySQL には便利な拡張機能が用意されており、適切に使用すればコーディング量を減らすことができる。今回は、REPLACE INTO を使う方法を紹介する。
REPLACE 構文は、プログラムからは INSERT と UPDATE を1文で実現するように見えるが、実際には INSERT と DELETE を MySQL が組み合わせて実行する。注意点は、下部を参照してほしい。
使い方
REPLACE 構文の使い方は、基本的には INSERT 構文と同じだ。SQL 文を見ると、INSERT が REPLACE INTO に変わっているが、あとは同じであることが分かる。
REPLACE INTO table ( id, category_name, display_order ) VALUES ( 1, 'カテゴリー1', 10 )
REPLACE INTO を使用した場合、テーブルの PRIMARY KEY か UNIQUE インデックスの値と、挿入しようとしているデータの値が同じであれば、既存の行を削除して INSERT を実行する。
まとめると、
- キーが一致する場合
-
- 既存の行を DELETE する
- 新しい行を INSERT する
- キーが一致しない場合
-
- 新しい行を INSERT する
という動作になる。
注意点
REPLACE 構文を利用した場合、INSERT と UPDATE の処理を分けた場合と実際の動作が異なる。キーが重複した場合、MySQL は DELETE を実行するためだ。REPLACE 構文を利用する際の注意点をまとめてみた。
- テーブルにプライマリーキーか、UNIQUE インデックスを用意しておかなければ REPLACE 構文は利用できない
- プライマリキーで AUTO_INCREMENT を利用している場合、REPLACE 構文の実行後にプライマリーキーの値が変わってしまう可能性がある(キーが一致した場合、既存の行を DELETE で削除してしまうため)
- REPLACE 構文が戻す行数は、影響を受けた行の総数である。INSERT のみ実行した場合は1、削除も実行した場合は2以上が戻る
- REPLACE 構文は MySQL の拡張であり、他のデータベースエンジンで利用できない。複数のデータベースエンジンに対応するようアプリケーションを作成する場合は、違いを吸収するような仕組みが必要になる
ピンバック: MySQL で INSERT と UPDATE を1文で実現する ~ ON DUPLICATE KEY UPDATE 編~ | UB Lab.