Demo :
INSERT INTO shop_commodity(shop_id,commodity_id,inventory_on_hand,unit_price,recommended,available
,created_by,created_at) VALUES (2324,122274,9999,58,1,1,11179751,sysdate()) on duplicate key update shop_id=shop_id , commodity_id=commodity_id;
批量插入数据:
INSERT INTO shop_commodity ( shop_id, commodity_id, inventory_on_hand, unit_price, recommended, available, created_by, created_at)
VALUES ( 2324, 34045, 9999, 4.5, 1, 1, 11179751, sysdate() ),
( 2324, 23366, 9999, 9.8, 1, 1, 11179751, sysdate() ),
( 2324, 23365, 9999, 9.8, 1, 1, 11179751, sysdate() )
ON DUPLICATE KEY UPDATE shop_id = shop_id, commodity_id = commodity_id;
Docs:
有时候我们需要用一个表去记录某些经常变动的数据,比如现在有一个表,是用来记录页面被访问的IP和访问次数的。你可以用传统的方法,只需要一个IP字段,只要客户端访问,就把IP写入表中。查询的时候用group by和count去统计每个IP的记录条数。但是这种方法很不理想,这种方法需要保存许多次IP,占资源就变多了。再就是记录如果多的话,查询的时候速度慢。这种情况我们会用另一种表结构来记录数据,把IP作为主键,再添加个记录访问次数的字段。这样就可以很轻松的查询数据,但是在写入数据的时候也许会遇到麻烦。你可能需要每次写入数据的时候都查询一次来判断到底是插入还是更新。其实,这个操作在MySQL是很容易实现的,不用我们自己去判断。因为主键约束本身就是唯一的,它自己会做这个判断。我们只需要在它判断有重复时执行一条更新语句就可以了。比如现在有一张名为iplog的表,主键是ip,存放IP地址。有一个整数类型的普通字段cnt,存放相应IP的访问次数。于是,我们可以用这样一条SQL语句来操作insert
into iplog(ip,cnt) values('127.0.0.1',1)
on duplicate key update cnt=cnt+1 前面的insert into部分就是普通的插入语句,正常情况就是插入这一条记录。但是如果遇到重复的情况就触发了on duplicate key update,会执行后面的cnt=cnt+1,这样数据就更新了。
但是有时候我们要做的不是每次数据的变化量都是1的简单的操作,比如现在有个用户表member,id是主键,score字段是账户的得分。这个score的变化量可不是每次都是固定的。那么依然可以用on duplicate key update来做insert
into member(id,score) values('127.0.0.1',100)
on duplicate key update score=score+values(score) 这里就使用了values(score)来指代insert中使用的那个values传入的score值。你可以把values看作一个对象,在插入语句中这个对象被定义了。在随后触发的on duplicate key update中使用它。使用的时候values里面的score相当与这个对象的键名。这个做法的好处就是不用把插入的数据在SQL语句中重复一次,如果插入的不是一个数字而是一个大字符串,这样使用就可以节省很多资源。
以上就是MySQL中实现“存在则更新,不存在则插入”的方法。在Oracle有个merge into是实现这个效果的,但是Oracle我不熟悉就不说了,如果需要的话问问百度和谷歌你就能得到一堆资料。