导读:很多时候我们在做数据插入的时候需要判断一下当前我插入的数据是否已经存在于数据库中。
一般情况下我们会写两条sql去操作
select 查询当前插入的数据是否已经存在
如果不存在就插入新的记录,如果存在就提示用户该记录已经存在
在mysql里面可以这么操作,如果记录存在就跳过或者更新,不存在就插入!
IGNORE
这个是根据插入表的主键和唯一索引去匹配的,如果当前插入的记录存在则跳过不插入。
INSERT IGNORE INTO `user` ('phone') VALUES ('18888888888');
此时user表中phone字段是唯一的,如果有这条记录则不执行插入操作,如果出现重复数据,将不返回错误,只是以警告形式返回。
on duplicate key update
主键或者唯一索引有重复时,则执行update操作
假设有一张表,id为主键,并且表中已经存在了id=1,likes=5的记录,此时下面两条sql等价。
INSERT INTO TABLENAME (id,likes) VALUES (1,18) ON DUPLICATE KEY UPDATE likes=likes+1;
UPDATE TABLENAME SET likes=likes+1 WHERE id=1;
如果是插入值,返回受影响行数为1,如果执行了更新操作那么返回的受影响行数为2.
如果条件是针对于主键操作的,那么此操作是无效操作,等同于ignore
如果一次性插入多条记录,此时id为主键,或者a是一个unique索引,并且表中已经存在id=1,likes=3的记录。
INSERT INTO TABLENAME (id,likes) VALUES (1,3),(1,7) ON DUPLICATE KEY UPDATE likes = likes+1;
执行后likes的值为变成5,因为在插入前已经存在了id=1的记录,上面的sql等于执行了两条update语句。
NOTE:INSERT INTO TABLENAME……ON DUPLICATE KEY UPDATE……,这样的sql中,假如插入的记录在表中一种有重复值(与主键、唯一索引匹配),那么则会执行update操作,如果在插入的时候表中没有重复值,那么就会执行insert操作。
问题:现在问题来了,如果INSERT多行记录, ON DUPLICATE KEY UPDATE后面字段的值怎么指定?要知道一条INSERT语句中只能有一个ON DUPLICATE KEY UPDATE,到底他会更新一行记录,还是更新所有需要更新的行。这个问题困扰了我很久了,其实使用VALUES()函数一切问题都解决了。
如果表中已经有id=1,likes=18 ;id=2,likes=19的两条记录,如果插入语句中有id=1或者id=2的记录,则更新原有记录,否则插入新行。
最后强调一下:
注意:ON DUPLICATE KEY UPDATE只是MySQL的特有语法,并不是SQL标准语法!
INSERT……SELECT……WHERE NOT EXISTS
NOTE:根据查询条件判断是否已经有对应的值,有的话跳过,没有的话执行插入,随便想查什么就查什么,这个用得最多。
REPLACE INTO
如果存与主键或者唯一索引相同的记录,那么则会先删除,然后在插入新记录。
注意:如果有两个主键或者唯一索引,必须要值全部匹配才会执行替换操作,否则执行插入操作,详情见官网。
MySQL对REPLACE(和 LOAD DATA ... REPLACE)使用以下算法 :
尝试将新行插入表中
插入失败,因为主键或唯一索引发生重复键错误:
从表中删除具有重复键值的冲突行
再次尝试将新行插入表中