程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> Mysql 原生語句中save or update 的寫法匯總

Mysql 原生語句中save or update 的寫法匯總

編輯:MySQL綜合教程

Mysql 原生語句中save or update 的寫法匯總。本站提示廣大學習愛好者:(Mysql 原生語句中save or update 的寫法匯總)文章只能為提供參考,不一定能成為您想要的結果。以下是Mysql 原生語句中save or update 的寫法匯總正文


配景

  在平凡的開辟中,常常碰著這類更新數據的場景:先斷定某一數據在庫表中能否存在,存在則update,不存在則insert。
假如應用Hibernate,它自帶saverOrUpdate辦法,用起來很便利,但如應用原生sql語句呢?
  老手最多見的寫法是,先經由過程select語句查詢記載能否存在,存在則應用update語句更新,不存在則應用insert語句拔出。
然則如許做顯著不敷優雅,存在幾個成績:
•為了履行一次更新操作,卻在法式中應用了兩次sql查詢語句,在體系負載比擬年夜的情形下,機能照樣會有影響的。
•代碼中存在if else語句,明明干了一件事,代碼卻很長。碼農都是懶人,能把工作簡略做的為啥要龐雜做呢:)。
 
那末成績來了,若何優雅的用sql語句完成saverOrUpdate?

  比來任務上也碰著相似更新數據的成績,寫多了也開端認為煩。記得Oracle下有Merge的寫法,就谷歌一下mysql的相似完成,整頓以下:
 
數據不存在則拔出,存在則無操作

   在insert語句中應用ignore症結字完成數據不存在則拔出,存在則無操作。它的完成邏輯是,當拔出語句湧現主鍵抵觸,或許獨一鍵抵觸時,不拋失足誤,直接疏忽這條拔出語句。官網上的相干引見以下:


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官方文檔中供給尺度的語法:


INSERT  IGNORE
    INTO tbl_name
    [PARTITION (partition_name,...)]
    [(col_name,...)]
    {VALUES | VALUE} ({expr | DEFAULT},...),(...),...

或許


INSERT IGNORE
    [INTO] tbl_name
    [PARTITION (partition_name,...)]
    [(col_name,...)]
    SELECT ...

可見除多了個IGNORE症結字之外,跟普通INSERT語句並沒有差別。

舉個栗子:

1.建一張測試用的表


CREATE TABLE `test_tab` (
  `name` varchar(64) NOT NULL,
  `age` int(11) NOT NULL,
  PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2.拔出一條數據


insert into `test_tab` (`name`,`age`) values ('zhangsan',24)

以後test_tab表的數據為:


name|age
:—-|:—
zhangsan|24

3.再履行一次步調2的拔出語句,則會報異常:


[Err] 1062 - Duplicate entry 'zhangsan' for key 'PRIMARY'

4.對步調2的insert語句增長ignore症結字,則不會報異常,已存在的數據也不會被更新。


insert IGNORE into `test_tab` (`name`,`age`) values ('zhangsan',24) ;

------
語句履行情形:
受影響的行: 0
時光: 0.000s


以後test_tab表的數據為:


name|age
:—-|:—
zhangsan|24

不存在則拔出,存在則更新,其一(應用DUPLICATE KEY UPDATE症結字)

   在insert語句中應用ON DUPLICATE KEY UPDATE症結字完成數據不存在則拔出,存在則更新的操作。斷定數據反復的邏輯仍然是主鍵抵觸或許獨一鍵抵觸。
官網上的相干引見以下:


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官方文檔中供給尺度的語法:


INSERT
    [INTO] tbl_name
    [PARTITION (partition_name,...)]
    [(col_name,...)]
    {VALUES | VALUE} ({expr | DEFAULT},...),(...),...
    [ ON DUPLICATE KEY UPDATE
      col_name=expr
        [, col_name=expr] ... ]

或許:


INSERT
    [INTO] tbl_name
    [PARTITION (partition_name,...)]
    SET col_name={expr | DEFAULT}, ...
    [ ON DUPLICATE KEY UPDATE
      col_name=expr
        [, col_name=expr] ... ]

或許:


INSERT
    [INTO] tbl_name
    [PARTITION (partition_name,...)]
    [(col_name,...)]
    SELECT ...
    [ ON DUPLICATE KEY UPDATE
      col_name=expr
        [, col_name=expr] ... ]

可見,照樣本來insert語句的寫法。
 
舉個栗子:

1.應用適才新建的test_tab表,此時表中的數據以下:


name|age
:—-|:—
zhangsan|24

2.應用主鍵雷同的insert語句,依然會duplicate key毛病


insert into `test_tab` (`name`,`age`) values ('zhangsan',50) ;
------------
[Err] 1062 - Duplicate entry 'zhangsan' for key 'PRIMARY'

3.對適才的insert語句添加 on duplicate key update … 症結字:


insert into `test_tab` (`name`,`age`) values ('zhangsan',50) 
ON DUPLICATE KEY UPDATE `age`=50 ;

------------
受影響的行: 2
時光: 0.025s


4.此時主鍵為'zhangsan'的數據,age字段已被更新:


name|age
:—-|:—
zhangsan|50

5.固然,假如主鍵不抵觸,後果跟普通拔出語句是一樣的:


insert into `test_tab` (`name`,`age`) values ('lisi',30) 
ON DUPLICATE KEY UPDATE `age`=30 ;

------------
受影響的行: 1
時光: 0.009s


name|age
:—-|:—
zhangsan|50
lisi|30

不存在則拔出,存在則更新,其二(應用replace語句完成)

   save or update 在mysql中還有另外一種完成,即replace into語句,它用起來有點像Oracle的Merge。斷定數據反復的邏輯仍然是主鍵或許獨一鍵抵觸。Mysql官方文檔中供給尺度的語法:


REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name
    [PARTITION (partition_name,...)]
    [(col_name,...)]
    {VALUES | VALUE} ({expr | DEFAULT},...),(...),...

或:


REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name
    [PARTITION (partition_name,...)]
    SET col_name={expr | DEFAULT}, ...

或:


REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name
    [PARTITION (partition_name,...)] 
    [(col_name,...)]
    SELECT ...

 
舉個栗子:

1.依然應用下面的test_tab表的數據,此時數據以下


name|age
:—-|:—
zhangsan|50
lisi|30

2.應用普通的insert語句拔出name=zhangsan的數據,報主鍵抵觸。然則換成replace into…語句則沒成績:


replace into `test_tab` (`name`,`age`) values ('zhangsan',30) ;

------------
受影響的行: 2
時光: 0.009s

3.成果以下:


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會招致營業邏輯凌亂。

所以當被更新表存在觸發器的場景時,應用INSERT的“DUPLICATE KEY UPDATE”症結字更適合。

以上就是本文所述的全體內容了,願望能讓年夜家更好的懂得mysql中的save和update語句。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved