MySQL insert 語法


insert 語句有三種語法:

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [(col_name [, col_name] ...)]
    { {VALUES | VALUE} (value_list) [, (value_list)] ...
      |
      VALUES row_constructor_list
    }
    [AS row_alias[(col_alias [, col_alias] ...)]]
    [ON DUPLICATE KEY UPDATE assignment_list]

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [AS row_alias[(col_alias [, col_alias] ...)]]
    SET assignment_list
    [ON DUPLICATE KEY UPDATE assignment_list]

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [(col_name [, col_name] ...)]
    [AS row_alias[(col_alias [, col_alias] ...)]]
    {SELECT ... | TABLE table_name}
    [ON DUPLICATE KEY UPDATE assignment_list]

value:
    {expr | DEFAULT}

value_list:
    value [, value] ...

row_constructor_list:
    ROW(value_list)[, ROW(value_list)][, ...]

assignment:
    col_name = [row_alias.]value

assignment_list:
    assignment [, assignment] ...


  • 1、INSERT 語句向已存在的表插入新行, INSERT ... VALUES, INSERT ... VALUES ROW(), 和 INSERT ... SET 這三種形式需要明確指定列的值,而 INSERT ... SELECT 形式是插入從其他一個或多個表查詢的結果。
  • 2、ON DUPLICATE KEY UPDATE 從句可以在 插入包含UNIQUE 索引 或 PRIMARY KEY 的列,且遇到該列的值已存在的情況時,選擇更新其他列,而不至於報錯。
  • 3、MySQL 8.0.19 及以后的版本中: 1) 可以使用 INSERT ... TABLE 來插入單表;2) 可以將插入行起個別名,用到 ON DUPLICATE KEY UPDATE 從句中,簡化書寫。
  • 4、完整的 INSERT 語句需要: 插入權限,更新權限,查詢權限。
  • 5、插入有分區的表時,需要使用 PARTITION 從句,后接分區名。如果插入行沒有匹配到分區,則失敗
  • 6、插入語句:1)如果指定了列名(可以部分列名),值可以通過 VALUES , VALUES ROW() , or SELECT 語句給出,值的順序和列名的順序要一致。2)如果沒有指定列名,則需要給出全部列的值,其順序與表結構中列的順序一致。
  • 7、在非 SQL 嚴格模式下,沒有指定的列則會用默認值(或隱式默認值)插入。而在嚴格模式下,如果某個列沒有指定默認值,且插入時沒有給該列指定一個值,則會報錯。建議 使用 DEFAULT 明確地設置列的默認值。
  • 8、如果列名和列值都為空,則插入一個所有列都是默認值的行
INSERT INTO tbl_name () VALUES();
  • 9、給會自動生成值的列指定值,只能指定 DEFAULT。自動生成值的列,指的是其值是通過其他列計算得到的,在創建表時指定了表達式。
  • 10、使用表達式時,可使用 DEFAULT(col_name) 給該列指定默認值
  • 11、在表達式中,可能會出現類型轉換。比如字符串 '1999.0e-2' 在插入 INT, FLOAT, DECIMAL(10,6), YEAR 類型的列時,會分別轉換為 1999, 19.9921, 19.992100, 1999
  • 12、使用表達式時,可以使用值列表中之前已經設置過的列。如果參考使用的是 AUTO_INCREMENT 的列(自增列沒有指定值),則自增列返回的值是0,因為 AUTO_INCREMENT 列是在其他列都賦值之后才生成的。
# 在設置 col2 的值時,使用了col1
INSERT INTO tbl_name (col1,col2) VALUES(15, col1*2);

# id 列自增,結果 col2 的值是 0
INSERT INTO tbl_name (col1,col2) VALUES(15, id*2);

#  id 列自增,結果 col2 的值是 200
INSERT INTO tbl_name (id,col1,col2) VALUES(100,15, id*2);


#  id 列自增,結果 col2 的值是 0
INSERT INTO tbl_name (id,col1,col2) VALUES(default, 15, id*2);
  • 13、多行插入
# 使用 values 形式
INSERT INTO tbl_name (a,b,c)   VALUES(1,2,3), (4,5,6), (7,8,9);

# 使用 values row 形式
INSERT INTO tbl_name (a,b,c)  VALUES ROW(1,2,3), ROW(4,5,6), ROW(7,8,9);
  • 14、使用 LOW_PRIORITY 修飾符,會延遲插入,等到沒有其他客戶端讀取這個表時,才執行插入語句,即插入優先級低於讀取優先級。 使用HIGH_PRIORITY 修飾符 提高 插入優先級,會覆蓋 --low-priority-updates 選項的作用。
    LOW_PRIORITY 和 HIGH_PRIORITY都只會影響使用表級鎖的引擎(如 MyISAM, MEMORY, and MERGE),也都會造成不能並發插入數據。

  • 15、使用 IGNORE 修飾符,會在執行插入語句時忽略一些可忽略的錯誤(並不是全部錯誤),而繼續完成數據的插入。比如 UNIQUE 索引 or PRIMARY KEY 的列 重復數據插入 的錯誤,就會忽略,但數據不會新增。

  • 16、

    • 1) INSERT ... SELECT 語句,可以通過查詢語句(SELECT)實現快速插入
    • 2)從 MySQL 8.0.19 版本開始,可以使用TABLE 代替 SELECT,用來將源表中的所有列插入到目標表中。 TABLE tb 等價於 SELECT * FROM tb。
    • 3)INSERT語句的目標表可能出現在查詢的SELECT部分的FROM子句中,或者作為TABLE 命名的表。但是,不能在子查詢中插入表同一表中的數據。
      能通過INSERT... SELECT 語句插入同一個表的數據,是因為MySQL會創建一個內部臨時表來保存SELECT中的行,然后將這些行插入到目標表中。另外該表本身不能是臨時表。
    • 4) INSERT ... SELECT 不允許並發插入
    • 5) INSERT ... SELECT 允許在 SELECT部分使用 別名,但 TABLE 語句不支持別名
TABLE table_name [ORDER BY column_name] [LIMIT number [OFFSET number]]
INSERT INTO tbl_temp2 (fld_id)
  SELECT tbl_temp1.fld_order_id
  FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;

# 從 MySQL 8.0.19 版本開始,可以使用TABLE 代替 SELECT
INSERT INTO ta TABLE tb;

# 插入本表中的數據
INSERT INTO computer_room (room_name, room_address, room_maintainer, creator_id) 
    SELECT room_name, room_address, room_maintainer, creator_id FROM computer_room WHERE id=7
  • 17、INSERT ... ON DUPLICATE KEY UPDATE, 可以處理 UNIQUE index or PRIMARY KEY 列 重復數據的問題
    • 1)ON DUPLICATE KEY UPDATE 從句 盡量避免包含多個唯一鍵的列,因為多個唯一鍵的列可能會匹配到多行,但也只修改一行。
    • 2)影響行數:如果插入新行是1;如果是更新行是2;如果新設置的值和原來一樣是0,但當連接到mysqld使用 mysql_real_connect() C API 函數且指定了CLIENT_FOUND_ROWS 標志,結果仍然是1,而不是0。
    • 3)無論是新增還是更新, LAST_INSERT_ID() 函數 返回的都是 AUTO_INCREMENT 的值
# a 是 唯一鍵,且已存在 a 為1的 行
# 下面兩個語句,結果類似:數據都會一樣,只是對於 InnoDB 的表 且 a 是自增的列 ,INSERT語句會增加  auto-incremen (自增)的值,UPDATE 語句不會。
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;

# 使用 VALUES(col_name),獲取語句中的相應列的值
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.19 后,  使用別名 替代 VALUES,獲取語句中的值 ,別名要唯一,能夠區分
# 行別名
INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6) AS new
  ON 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;

# set 形式語句
INSERT INTO t1 SET a=1,b=2,c=3 AS new
  ON 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;

## 從 MySQL 8.0.20 開始,INSERT ... SELECT ... ON DUPLICATE KEY UPDATE 中的 UPDATE 使用 VALUES(),會拋出warning
INSERT INTO t1
  SELECT c, c+d FROM t2
  ON DUPLICATE KEY UPDATE b = VALUES(b);

# 使用子查詢替換,就不會有警告
INSERT INTO t1
  SELECT * FROM (SELECT c, c+d AS e FROM t2) AS dt
  ON DUPLICATE KEY UPDATE b = e;


# 直接使用聯合查詢會報錯
INSERT INTO t1 (a, b)
  SELECT c, d FROM t2
  UNION
  SELECT e, f FROM t3
ON DUPLICATE KEY UPDATE b = b + c;

# 需要 將聯合查詢作為一個整體的導出表
INSERT INTO t1 (a, b)
   SELECT * FROM
      (SELECT c, d FROM t2
       UNION
       SELECT e, f FROM t3) AS dt
ON DUPLICATE KEY UPDATE b = b + c;
  • 18、DELAYED 修飾符: 在 MySQL 5.6 就過時了,在 MySQL8.0 后 已經不支持了,會忽略這個關鍵詞。其過程是:立即響應發起插入請求的客戶端,但插入語句先排隊,等到該表沒有其他線程使用時執行插入語句。

https://dev.mysql.com/doc/refman/8.0/en/insert.html
https://dev.mysql.com/doc/refman/8.0/en/insert-select.html
https://dev.mysql.com/doc/refman/8.0/en/table.html
https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM