我们在数据库相关的开发中经常遇到这样一个问题:向数据库表中插入某条记录,若是存在就对其进行更新。例如,有如下数据表user(id为主键):

 

idnamepasswd
1usr1pswd1
.........

 向其插入id=1,name=usr1,passwd=pswd2的记录,若存在id=1的记录,则对其进行更新操作。

    这个问题在单连接访问的条件下下很简单,可以先对记录执行UPDATE操作,若影响的条数为0,说明没有此记录,然后可以放心大胆的进行INSERT操作。

    但是在多并发访问的条件下,上述做法则存在同步问题。若是引入事务则又显得有些小题大做,若是能有一条语句以原子操作的方式完成上述功能那便是极好的。现将MySQL与Oracle的处理办法总结如下。


1、MySQL


    MySQL有两种处理方式:REPLACE 和 ON DUPLICATE KEY

    

    (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');