MYSQL教程Mysql 原生语句中save or update 的写法汇总

MYSQL教程Mysql 原生语句中save or update 的写法汇总,第1张

概述介绍《MYSQL教程Mysql 原生语句中save or update 的写法汇总》开发教程,希望对您有用。

《MysqL教程MysqL 原生语句中save or update 的写法汇总》要点:
本文介绍了MysqL教程MysqL 原生语句中save or update 的写法汇总,希望对您有用。如果有疑问,可以联系我们。

配景MysqL学习

  在平常的开发中,经常碰到这种更新数据的场景:先判断某一数据在库表中是否存在,存在则update,不存在则insert.
如果使用Hibernate,它自带saverOrUpdate办法,用起来很方便,但如使用原生SQL语句呢?
  新手最常见的写法是,先通过select语句查询记录是否存在,存在则使用update语句更新,不存在则使用insert语句插入.
但是这样做明显不够优雅,存在几个问题:
•为了执行一次更新 *** 作,却在程序中使用了两次SQL查询语句,在系统负载比较大的情况下,性能还是会有影响的.
•代码中存在if else语句,明明干了一件事,代码却很长.码农都是懒人,能把事情简单做的为啥要复杂做呢:).
 
那么问题来了,如何优雅的用SQL语句实现saverOrUpdate?MysqL学习

  最近工作上也碰到类似更新数据的问题,写多了也开始觉得烦.记得Oracle下有Merge的写法,就Google一下MysqL的类似实现,整理如下:
 
数据不存在则插入,存在则无 *** 作MysqL学习

   在insert语句中使用ignore关键字实现数据不存在则插入,存在则无 *** 作.它的实现逻辑是,当插入语句出现主键冲突,或者唯一键冲突时,不抛出错误,直接忽略这条插入语句.官网上的相关介绍如下:MysqL学习


If you use the IGnorE keyword,errors that occur while executing the INSERT statement are ignored. For example,without IGnorE,a row that duplicates an existing UNIQUE index or PRIMARY KEY value in the table causes a duplicate-key error and the statement is aborted. With IGnorE,the row is discarded and no error occurs. Ignored errors may generate warnings instead,although duplicate-key errors do not.

MysqL官方文档中提供标准的语法:MysqL学习

代码如下:
INSERT  IGnorE
    INTO tbl_name
    [PARTITION (partition_name,...)]
    [(col_name,...)]
    {VALUES | VALUE} ({expr | DEFAulT},...),(...),...

或者MysqL学习

代码如下:
INSERT IGnorE
    [INTO] tbl_name
    [PARTITION (partition_name,...)]
    SELECT ...

可见除了多了个IGnorE关键字以外,跟一般INSERT语句并无区别.
MysqL学习

举个栗子:MysqL学习

1.建一张测试用的表MysqL学习

代码如下:
CREATE table `test_tab` (
  `name` varchar(64) NOT NulL,
  `age` int(11) NOT NulL,
  PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAulT CHARSET=utf8;

2.插入一条数据MysqL学习

代码如下:
insert into `test_tab` (`name`,`age`) values ('zhangsan',24)

当前test_tab表的数据为:MysqL学习

代码如下:
name|age
:―-|:―
zhangsan|24

3.再执行一次步骤2的插入语句,则会报异常:MysqL学习

代码如下:
[Err] 1062 - Duplicate entry 'zhangsan' for key 'PRIMARY'

4.对步骤2的insert语句增加ignore关键字,则不会报异常,已存在的数据也不会被更新.MysqL学习

代码如下:
insert IGnorE into `test_tab` (`name`,24) ;

------
语句执行情况:
受影响的行: 0
时间: 0.000s


当前test_tab表的数据为:MysqL学习

代码如下:
name|age
:―-|:―
zhangsan|24

不存在则插入,存在则更新,其一(使用DUPliCATE KEY UPDATE关键字)MysqL学习

   在insert语句中使用ON DUPliCATE KEY UPDATE关键字实现数据不存在则插入,存在则更新的 *** 作.判断数据重复的逻辑依然是主键冲突或者唯一键冲突.
官网上的相关介绍如下:MysqL学习


if you specify ON DUPliCATE KEY UPDATE,and a row is inserted that would cause a duplicate value in a UNIQUE index or PRIMARY KEY,an UPDATE of the old row is performed. The affected-rows value per row is 1 if the row is inserted as a new row,2 if an existing row is updated,and 0 if an existing row is set to its current values.

MysqL官方文档中提供标准的语法:MysqL学习

代码如下:
INSERT
    [INTO] tbl_name
    [PARTITION (partition_name,...
    [ ON DUPliCATE KEY UPDATE
      col_name=expr
        [,col_name=expr] ... ]

或者:MysqL学习

代码如下:
INSERT
    [INTO] tbl_name
    [PARTITION (partition_name,...)]
    SET col_name={expr | DEFAulT},col_name=expr] ... ]

或者:MysqL学习

代码如下:
INSERT
    [INTO] tbl_name
    [PARTITION (partition_name,...)]
    SELECT ...
    [ ON DUPliCATE KEY UPDATE
      col_name=expr
        [,col_name=expr] ... ]

可见,还是本来insert语句的写法.
 
举个栗子:MysqL学习

1.使用刚才新建的test_tab表,此时表中的数据如下:MysqL学习

代码如下:
name|age
:―-|:―
zhangsan|24

2.使用主键相同的insert语句,仍然会duplicate key错误MysqL学习

代码如下:
insert into `test_tab` (`name`,50) ;
------------
[Err] 1062 - Duplicate entry 'zhangsan' for key 'PRIMARY'

3.对刚才的insert语句添加 on duplicate key update … 关键字:MysqL学习

代码如下:
insert into `test_tab` (`name`,50) 
ON DUPliCATE KEY UPDATE `age`=50 ;

------------
受影响的行: 2
时间: 0.025sMysqL学习


4.此时主键为'zhangsan'的数据,age字段已被更新:MysqL学习

代码如下:
name|age
:―-|:―
zhangsan|50

5.当然,如果主键不冲突,效果跟一般插入语句是一样的:MysqL学习

代码如下:
insert into `test_tab` (`name`,`age`) values ('lisi',30) 
ON DUPliCATE KEY UPDATE `age`=30 ;

------------
受影响的行: 1
时间: 0.009sMysqL学习

代码如下:
name|age
:―-|:―
zhangsan|50
lisi|30

不存在则插入,其二(使用replace语句实现)MysqL学习

   save or update 在MysqL中还有另一种实现,即replace into语句,它用起来有点像Oracle的Merge.判断数据重复的逻辑依然是主键或者唯一键冲突.MysqL官方文档中提供标准的语法:MysqL学习

代码如下:
REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name
    [PARTITION (partition_name,...

或:MysqL学习

代码如下:
REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name
    [PARTITION (partition_name,...)]
    SET col_name={expr | DEFAulT},...

或:MysqL学习

代码如下:
REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name
    [PARTITION (partition_name,...)] 
    [(col_name,...)]
    SELECT ...

 
举个栗子:

1.仍然使用上面的test_tab表的数据,此时数据如下MysqL学习

代码如下:
name|age
:―-|:―
zhangsan|50
lisi|30

2.使用一般的insert语句插入name=zhangsan的数据,报主键冲突.但是换成replace into…语句则没问题:MysqL学习

代码如下:
replace into `test_tab` (`name`,30) ;

------------
受影响的行: 2
时间: 0.009sMysqL学习

3.结果如下:MysqL学习

代码如下:
name|age
:―-|:―
zhangsan|30
lisi|30

  对于 *** 作结果来说,很像是save or update,但是实现方式与INSERT的“DUPliCATE KEY UPDATE”关键字不同.当使用replace into语句时,对于重复的数据,是直接删除,然后再插入新数据的.所以它的更新其实不是update,而是delete->insert.大多数情况下,使用replace into完成更新 *** 作并无问题,但是有一种场景必须特别注意:
•当被更新的表,存在insert,update,和delete触发器时,使用replace语句必须特别小心.因为依照业务逻辑,更新完数据后,应该触发update触发器,但是使用replace语句的话,会触发delete和insert触发器,如果update触发器有一些特殊 *** 作(比如记录 *** 作日志)的话,使用replace会导致业务逻辑混乱.MysqL学习

所以当被更新表存在触发器的场景时,使用INSERT的“DUPliCATE KEY UPDATE”关键字更合适.MysqL学习

以上便是本文所述的全部内容了,希望能让大家更好的理解MysqL中的save和update语句.MysqL学习

欢迎参与《MysqL教程MysqL 原生语句中save or update 的写法汇总》讨论,分享您的想法,内存溢出PHP学院为您提供专业教程。

总结

以上是内存溢出为你收集整理的MYSQL教程Mysql 原生语句中save or update 的写法汇总全部内容,希望文章能够帮你解决MYSQL教程Mysql 原生语句中save or update 的写法汇总所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/sjk/1154410.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-01
下一篇 2022-06-01

发表评论

登录后才能评论

评论列表(0条)

保存