背景:在向数据库中插入语句,尤其是插入的字段包含了主键或者唯一索引时。总是需要先判断要插入的该主键或唯一索引字段值在数据表中是否已经存在,之后还需要依据判断的结果决定是进行添加操作还是修改操作。今天无意发现mysql可以将这个简化的用法,找了些资料,调试完成后将经验总结下。
实现方式有:
1.ON DUPLICATE KEY UPDATE 原理:在确定主键值已经存在后,会进行update修改操作。(可以指定修改的字段,这样可以不影响其他字段的值)
2.REPLACE INTO 原理:在确定主键值已经存在后,会先进行delete删除操作,再进行insert添加操作。(因为是先删除后添加,所以会影响其他字段的值。如果添加的字段值包含了所有的列,可以用这种方式,其他不推荐,会导致数据错误)
上代码部分:
1.REPLACE INTO
REPLACE INTO ecm_goods_status(goods_id,if_stock,stock_price) values(3264604,1,25)
红色框区域的值已经丢失
2.ON DUPLICATE KEY UPDATE
INSERT INTO ecm_goods_status(goods_id,if_stock,stock_price) VALUES(3264604,1,15)
ON DUPLICATE KEY UPDATE if_stock=1,stock_price=VALUES(stock_price)
完成需要的操作,并且红色框区域的数据没有丢失
3.ON DUPLICATE KEY UPDATE 多行多列操作(VALUES函数为获取对应列值)
INSERT INTO ecm_goods_status(goods_id,if_stock,stock_price) VALUES(3264427,1,50.00),(3264430,1,2.00),(3264604,1,8.00) ON DUPLICATE KEY UPDATE if_stock=1,stock_price=VALUES(stock_price)
4.ON DUPLICATE KEY UPDATE 直接使用查询结果(别名字段不能使用,会导致mysql报识别不了列名的错误)INSERT INTO ecm_goods_status(goods_id,if_stock,stock_price)
select goods_id,1 as if_stock,pro_special_price
from ecm_market_activity_apply
where goods_id > 0
and ma_type= 21
and status=2
ON DUPLICATE KEY UPDATE if_stock=1,stock_price=pro_special_price
列别名报错的情况
INSERT INTO ecm_goods_status(goods_id,if_stock,stock_price)
select goods_id,1 as if_stock,min(pro_special_price) as price
from ecm_market_activity_apply
where goods_id > 0
and ma_type= 21
and status=2
GROUP BY goods_id
ON DUPLICATE KEY UPDATE if_stock=1,stock_price=price