データベースINSERT OR UPDATE問題まとめ


データベース関連の開発では、データベース・テーブルにレコードを挿入し、存在する場合は更新するという問題がよく発生します.たとえば、次のデータテーブルuser(idはプライマリ・キー)があります.
 
id
name
passwd
1
usr1
pswd1
...
...
...
id=1,name=usr 1,passwd=pswd 2のレコードを挿入し,id=1のレコードがあれば更新操作を行う.
この問題は単一接続アクセスの条件下では簡単で,まず記録に対してUPDATE操作を実行することができ,影響する本数が0であれば,この記録がないことを説明し,安心して大胆にINSERT操作を行うことができる.
しかし、複数の同時アクセスの条件下では、上記の方法では同期の問題があります.トランザクションを導入すると大げさに見えますが、上記の機能を原子操作で完成させる文があれば素晴らしいです.MySQLとOracleの処理方法を以下にまとめます.
1、MySQL
MySQLには、REPLACEとON DUPLICATE KEYの2つの処理方法があります
    
    (1)REPLACE
REPLACEはINSERTの文法と似ていて、形式は以下の通りです.
replace into table(col1,col2,...) values(val1,val2,...);

例:
replace into user(id,name,passwd) values(1,'usr1','pawd2');

挿入されたレコードとテーブル内の既存のレコードが重複しない場合、INSERT操作を実行し、影響するレコード数は1である.挿入されたレコードがテーブルの既存のレコードと重複する場合は、DELETEの既存のレコードを先に実行し、INSERTを実行し、影響するレコード数は2となる.
    (2)ON DUPLICATE KEY
ON DUPLICATE KEY文は、実行するINSERT文とUPDATE文を接続しています.形式は次のとおりです.
insert_statement on duplicate key update_statement

例:
insert into user(id,name,passwd) values(1,'usr1','pswd2') 
on duplicate key update name='usr1',passwd='pswd2';

挿入されたレコードが表の既存のレコードと重複しない場合、前半のINSERT操作を実行し、影響するレコード数は1である.挿入したレコードが表の既存のレコードと重複する場合は、後半のUPDATE操作を行い、影響するレコード数は2とする.
2、Oracle
Oracleでは、主にmerge文を使用して処理されます.例:
merge into user using(select 1 id,'usr1','pswd2' from dual) t on (t.id=user.id)
when matched then
    update set user.name='usr1',user.passwd='pswd2'
when not matched then
    insert (user.id,user.name,user.passwd) values(1,'usr1','pswd2');