mysql-on duplicate key update实现insertOrUpdate官方文档
【README】
mysql 基于 on duplicate key update filed=value ; 實現有則更新,沒有則插入;
以下內容總結于? https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html
【1】api 描述
如果指定 ON DUPLICATE KEY UPDATE 子句并且要插入的行會導致 UNIQUE 索引或 PRIMARY KEY 中出現重復值,則會發生舊行的 UPDATE。 例如,如果列 a 聲明為 UNIQUE 并包含值 1,則以下兩個語句具有類似的效果:
INSERT INTO t1 (a,b,c) VALUES (1,2,3)ON DUPLICATE KEY UPDATE c=c+1;UPDATE t1 SET c=c+1 WHERE a=1;效果并不完全相同:對于 a 是自增列的 InnoDB 表,INSERT 語句增加自增值,但 UPDATE 不會。如果列 b 也是唯一的,則 INSERT 等效于此 UPDATE 語句:
UPDATE t1 SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;也就說, 表t1 要有唯一鍵,才能保證實現新增或更新的效果; 因為主鍵肯定不一樣;
注意:如果 a=1 OR b=2 匹配多行,則只更新一行。 通常,您應該盡量避免在具有多個唯一索引的表上使用 ON DUPLICATE KEY UPDATE 子句。
【1.1】更新行數
使用 ON DUPLICATE KEY UPDATE,如果將行作為新行插入,則每行的受影響行值為 1,如果更新現有行,則為 2,如果現有行設置為其當前值,則為 0。 如果在連接到 mysqld 時為 mysql_real_connect() C API 函數指定 CLIENT_FOUND_ROWS 標志,則如果現有行設置為其當前值,則受影響的行值為 1(而不是 0)。
【1.2】可以更新多個列
ON DUPLICATE KEY UPDATE 子句可以包含多個列分配,以逗號分隔。
INSERT INTO t1 (a,b,c) VALUES (1,2,3)ON DUPLICATE KEY UPDATE c=c+1, c2=2, c3=3;【1.3】 values() 函數引用值
可以使用 VALUES(col_name) 函數來引用來自 INSERT ... ON DUPLICATE KEY UPDATE 語句的 INSERT 部分的列值。 換句話說,ON DUPLICATE KEY UPDATE 子句中的 VALUES(col_name) 是指將插入的 col_name 的值,沒有發生重復鍵沖突。 此函數在多行插入中特別有用。 VALUES() 函數僅在 ON DUPLICATE KEY UPDATE 子句或 INSERT 語句中有意義,否則返回 NULL。 例子:
INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6)ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b); -- 等價于 INSERT INTO t1 (a,b,c) VALUES (1,2,3)ON DUPLICATE KEY UPDATE c=3; INSERT INTO t1 (a,b,c) VALUES (4,5,6)ON DUPLICATE KEY UPDATE c=9;注意: 從 MySQL 8.0.20 開始,不推薦使用 VALUES() 來引用新的行和列(可能會被刪除),并且在未來的 MySQL 版本中可能會被刪除。 相反,使用行和列別名,如本節接下來的幾段所述。
【1.4】為行使用別名(mysql8.0.19才可以,注意版本)
從 MySQL 8.0.19 開始,可以為行使用別名,可以選擇插入一個或多個列,在 VALUES 或 SET 子句之后,并以 AS 關鍵字開頭。 使用行別名 new,前面顯示的使用 VALUES() 訪問新列值的語句可以寫成如下所示的形式:
INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6) AS newON DUPLICATE KEY UPDATE c = new.a+new.b;-- 等價于INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6) AS new(m,n,p)ON DUPLICATE KEY UPDATE c = m+n;補充: 從 MySQL 8.0.20 開始,在 UPDATE 子句中使用 VALUES() 的 INSERT ... SELECT ... ON DUPLICATE KEY UPDATE 語句會拋出警告:
INSERT INTO t1SELECT c, c+d FROM t2ON DUPLICATE KEY UPDATE b = VALUES(b);-- 等價于 INSERT INTO t1SELECT * FROM (SELECT c, c+d AS e FROM t2) AS dtON DUPLICATE KEY UPDATE b = e;【1.5】將行和列別名與 SET 子句一起使用,而不用values
在剛剛顯示的兩個 INSERT ... ON DUPLICATE KEY UPDATE 語句中使用 SET 而不是 VALUES 可以如下所示完成:
INSERT INTO t1 SET a=1,b=2,c=3 AS newON DUPLICATE KEY UPDATE c = new.a+new.b;INSERT INTO t1 SET a=1,b=2,c=3 AS new(m,n,p)ON DUPLICATE KEY UPDATE c = m+n;【1.6】行別名不能與表名相同。
如果未使用列別名,或者它們與列名相同,則必須使用 ON DUPLICATE KEY UPDATE 子句中的行別名來區分它們。 列別名對于它們所應用的行別名必須是唯一的(即,沒有引用同一行列的列別名可能是相同的)。
【2】insert ... select ... on duplicate key update (不建議使用,不安全,參見文末)
對于 INSERT ... SELECT 語句,這些規則適用于可以在 ON DUPLICATE KEY UPDATE 子句中引用的可接受形式的 SELECT 查詢表達式:
- 對來自單個表(可能是派生表)的查詢的列的引用。
- 對多個表的連接查詢中的列的引用。
- 對來自 DISTINCT 查詢的列的引用。
- 引用其他表中的列,只要 SELECT 不使用 GROUP BY。 一個副作用是您必須限定對非唯一列名的引用。
【2.1】不支持從 UNION 引用列。
要解決此限制,請將 UNION 重寫為派生表,以便可以將其行視為單表結果集。 例如,此語句會產生錯誤(語法錯誤):
INSERT INTO t1 (a, b)SELECT c, d FROM t2UNIONSELECT e, f FROM t3 ON DUPLICATE KEY UPDATE b = b + c;相反,使用將 UNION 重寫為派生表的等效語句(語法正確):
INSERT INTO t1 (a, b) SELECT * FROM(SELECT c, d FROM t2UNIONSELECT e, f FROM t3) AS dt ON DUPLICATE KEY UPDATE b = b + c;【2.2】支持group by
將查詢重寫為派生表的技術還支持從 GROUP BY 查詢引用列。
【2.3】INSERT ... SELECT ON DUPLICATE KEY UPDATE 語句是不安全的
因為 INSERT ... SELECT 語句的結果取決于來自 SELECT 的行的順序,并且無法始終保證此順序,所以在記錄 INSERT ... SELECT ON DUPLICATE KEY UPDATE 語句時源和副本可能會出現分歧 . 因此,對于基于語句的復制,INSERT ... SELECT ON DUPLICATE KEY UPDATE 語句被標記為不安全(謹慎使用 insert ... select on duplicate key update )。
此類語句在使用基于語句的模式時會在錯誤日志中產生警告,并在使用 MIXED 模式時使用基于行的格式寫入二進制日志。 針對具有多個唯一鍵或主鍵的表的 INSERT ... ON DUPLICATE KEY UPDATE 語句也被標記為不安全。 (錯誤#11765650,錯誤#58637)
總結
以上是生活随笔為你收集整理的mysql-on duplicate key update实现insertOrUpdate官方文档的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 北峰对讲机链接电脑(北峰对讲机官网电话)
- 下一篇: 世界最贵的电脑主机(全世界最贵的电脑)