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語句。