慎用replace into

不记得是在哪里看到说replace into的工作流程是根据主键或者唯一索引来判断记录是否存在,不存在就插入,存在则更新.

然后在框架的orm里面针对mysql的驱动实现了一个replace的方法,而然今天使用的时候出现了问题:

mysql> select * from tbl_user;
+----+--------+--------+
| id | name   | status |
+----+--------+--------+
|  1 | eslizn |      0 |
+----+--------+--------+
1 row in set (0.00 sec)

这里是当前表数据,然后我需要更新这条记录的status字段,但是我不确定这条id=1的记录是否存在,于是我使用replace into:

mysql> replace into tbl_user (id, status) values (1, 1);
Query OK, 2 rows affected (0.00 sec)

是不是哪里不对?受影响的行数为何为2?我们再看下数据:

mysql> select * from tbl_user;
+----+------+--------+
| id | name | status |
+----+------+--------+
|  1 | NULL |      1 |
+----+------+--------+
1 row in set (0.00 sec)

可以看到name已经变成null,其原因就是replace into并非是存在则更新,而是存在则删除并插入.

在mysql里不存在就写入,存在则更新的正确写法是这样:

insert into tbl_user (id, status) values (1, 1) on duplicate key update status = 1;

主键冲突时则更新

附上oracle的merge into:

merge into tbl_user using (
    select
        count (*) as nums
    from
        tbl_user
    where
        tbl_user.pid = 'pid'
) p on (p.nums <> 0)
when matched then update set tbl_user.status = 1 where tbl_user.pid = 'pid'
when not matched then insert (tbl_user.pid, tbl_user.status) values ('pid', 1);

标签: mysql, replace, oracle, merge

添加新评论