MySQL的SQL語句 - 數據操做語句(6)- 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] ...
 
INSERT 語句在現有表中插入新行。INSERT ... VALUESINSERT ... VALUES ROW() 和 INSERT ... SET 根據顯式指定的值插入行。INSERT ... SELECT 將從另外一個或多個表中選擇的行插入表中。在 MySQL 8.0.19 及更高版本中也可使用 INSERT ... TABLE 語句插入單個表中的行。若是 INSERT 語句帶有ON DUPLICATE KEY UPDATE 子句,若是插入的行與惟一索引或者主鍵索引重複時,能夠更新現有行。在 MySQL 8.0.19 及更高版本中,具備一個或多個可選列別名的行別名能夠與 ON DUPLICATE KEY UPDATE 一塊兒使用,以引用要插入的行。   在 MySQL 8.0 中,DELAYED 關鍵字被服務器接受但會被忽略。   向表插入數據須要該表的 INSERT 權限。若是使用了 ON DUPLICATE KEY UPDATE 子句,而且因爲重複鍵致使更新了數據,則語句須要更新列的UPDATE 權限。對於已讀取但未修改的列,只須要 SELECT 權限(例如,對於只在 ON DUPLICATE KEY UPDATE 子句中 col_name=expr 賦值右側引用的列)。   向分區表插入數據時,能夠控制哪些分區和子分區接受新行。PARTITION 選項接受表的逗號分隔的一個或多個分區或子分區(或二者)的名稱列表。若是給定 INSERT 語句要插入的任何行與列出的分區不匹配,則INSERT 語句將失敗,並出現錯誤提示:Found a row not matching the given partition set   可使用 REPLACE 而不是 INSERT 來覆蓋舊行。REPLACE 是在處理包含重複舊行的惟一鍵值的新行時 INSERT IGNORE 語句的對應項:新行替換舊行,而不是被丟棄。   tbl_name 是應該插入行的表。指定語句爲其提供值的列,以下所示:   ● 在表名後面提供由括號括起來的逗號分隔的列名列表。在這種狀況下,每一個命名列的值必須由 VALUES 列表、VALUES ROW() 列表或 SELECT語句提供。對於 INSERT TABLE 形式,源表中的列數必須與要插入的列數匹配。   ● 若是不想爲 INSERT ... VALUES 或 INSERT ... SELECT 指定列名列表,表中每列的值必須由 VALUES 列表、SELECT 語句或 TABLE 語句提供。若是不知道表中列順序,請使用 DESCRIBE tbl_name 語句來查找。   ● SET 子句經過名稱和每一個列的賦值顯式指示列。   列值能夠用幾種方式給出:   ● 若是未啓用嚴格 SQL 模式,則任何未顯式給定值的列都將設置爲其默認值(顯式或隱式)。例如,若是指定的列表沒有列出表中的全部列,則未列出的列將設置爲其默認值。   若是啓用了嚴格 SQL 模式,若是 INSERT 語句沒有爲每一個沒有默認值的列指定顯式值,則會引起錯誤。   ● 若是列列表和 VALUES 列表都爲空,則 INSERT 將建立一行,並將每一個列設置爲其默認值:  

INSERT INTO tbl_name () VALUES();
 
若是未啓用嚴格模式,MySQL 將對沒有顯式定義默認值的任何列使用隱式默認值。若是啓用了嚴格模式,則若是任何列沒有默認值,則會發生錯誤。   ● 使用關鍵字 DEFAULT 將列顯式設置爲其默認值。這使得編寫將值分配給除少數列以外的全部列的 INSERT 語句變得更加容易,由於這樣能夠避免編寫不完整的 VALUES 列表,不然,必須提供與 VALUES 列表中每一個值對應的列名列表。   ● 若是顯式插入生成的列,則惟一容許的值是 DEFAULT   ● 在表達式中,可使用 DEFAULT(col_name爲列 col_name 生成默認值。   ● 若是表達式數據類型與列數據類型不匹配,則可能會發生提供列值的表達式 expr 的類型轉換。根據列類型,轉換給定值可能會致使不一樣的插入值。例如,在INTFLOATDECIMAL(10,6) 或 YEAR 列中插入字符串'1999.0e-2' 將分別插入值199919.992119.9921001999。存儲在 INT和 YEAR 列中的值是1999,由於字符串到數字的轉換隻查看字符串初始部分中可能被視爲有效整數或年份的部分。對於 FLOAT 和 DECIMAL 列,字符串到數字的轉換將整個字符串視爲有效的數值。   ● 表達式 expr 能夠引用以前在值列表中設置的任何列。例如,能夠執行下面的語句,由於 col2 的值引用了 col1,而 col1 以前已經賦值了:  

INSERT INTO tbl_name (col1,col2) VALUES(15,col1*2);
 
但如下語句是不合法的,由於 col1 的值引用了 col2,而 col2 在 col1 以後賦值:  

INSERT INTO tbl_name (col1,col2) VALUES(col2*2,15);
 
包含 AUTO_INCREMENT 值的列會出現異常。由於 AUTO_INCREMENT 值是在其餘值賦值以後生成的,賦值中對 AUTO_INCREMENT 列的任何引用都會返回 0   使用 VALUES 語法的 INSERT 語句能夠插入多行。爲此,請包含多個逗號分隔列值的列表,列表用括號括起來,用逗號分隔。例如:  


INSERT INTO tbl_name (a,b,c)    VALUES(1,2,3), (4,5,6), (7,8,9);
 
每一個值列表必須包含與每行插入的值個數相同的值。如下語句無效,由於它包含一個9個值的列表,而不是每一個包含三個值的三個列表:  

INSERT INTO tbl_name (a,b,c) VALUES(1,2,3,4,5,6,7,8,9);
 
在此上下文中,VALUE 是 VALUES 的同義詞。既不表示值列表的數量,也不表示每一個列表的值的數量。不管是單個值列表仍是多個列表,均可以使用,與每一個列表中的值的數量無關。   使用 VALUES ROW() 語法的 INSERT 語句也能夠插入多行。在這種狀況下,每行的值都必須包含在 ROW() 中(行構造器):  


INSERT INTO tbl_name (a,b,c)    VALUES ROW(1,2,3), ROW(4,5,6), ROW(7,8,9);
 
可使用 ROW_COUNT() SQL 函數或 mysql_affected_rows() C API 函數獲取INSERT 語句的影響行數。   若是使用 INSERT ... VALUES 或者有多個值列表的 INSERT ... VALUES ROW() 語句,或 INSERT ... SELECTINSERT ... TABLE 中,語句將返回如下格式的信息字符串:  

Records: N1 Duplicates: N2 Warnings: N3
 
若是使用的是 C API,則能夠經過調用 mysql_info() 函數來獲取信息字符串。   Records 表示語句處理的行數。(這不必定是實際插入的行數,由於重複項可能不爲零。)Duplicates 表示沒法插入的行數,由於它們與某些現有的惟一索引值重複。Warnings 表示嘗試插入在某些方面有問題的列值的次數。在如下任何狀況下均可能出現警告:   ● 向已聲明爲 NOT NULL 的列中插入 NULL。對於多行 INSERT 語句或INSERT INTO ... SELECT 語句,列被設置爲列數據類型的隱式默認值。數字類型爲0,字符串類型爲空字符串(''),日期和時間類型爲「zero」。INSERT INTO ... SELECT 語句的處理方式與多行插入相同,由於服務器不會檢查SELECT 的結果集是否返回單行。(對於單行 INSERT,將 NULL 插入 NOT NULL 列時不會出現警告。相反,該語句將失敗並提示錯誤。)   ● 將數值列設置爲列範圍以外的值。該值將被剪裁到範圍最接近的極值。   ● 將值(如'10.34 a')分配給數值列。去掉尾部的非數字文本並插入剩餘的數字部分。若是字符串值沒有前導數字部分,則將列設置爲0   ● 將超過列最大長度的字符串插入列(CHARVARCHARTEXT BLOB),值被截斷爲列的最大長度。   ● 在日期或時間列中插入數據類型非法的值。該列被設置爲相應類型的適當零值。   ● 若是 INSERT 語句向有 AUTO_INCREMENT 列的表中插入一行,可使用 LAST_INSERT_ID() SQL 函數或 mysql_INSERT_ID() C API 函數來查找該列使用的值。   INSERT 語句支持如下修飾符:   ● 若是使用 LOW_PRIORITY 修飾符,INSERT 的執行將被延遲,直到沒有其餘客戶端從表中讀取數據。這包括在現有客戶端讀取時已經在讀的其餘客戶端,以及正在等待的 INSERT LOW_PRIORITY 語句。所以,發出INSERT LOW_PRIORITY 語句的客戶端可能要等待很長時間。   低優先級隻影響只使用表級鎖定(如 MyISAM、MEMORY 和 MERGE)的存儲引擎。   ● 若是指定 HIGH_PRIORITY,則它會覆蓋 --low-priority-updates 選項(若是服務器是用該選項啓動的)的設置。它還致使不使用併發插入。   HIGH_PRIORITY 隻影響只使用表級鎖定(如 MyISAMMEMORY MERGE)的存儲引擎。   ● 若是使用 IGNORE 修飾符,則會忽略執行 INSERT 語句時發生的可忽略錯誤。例如,沒有 IGNORE,若是行與表中現有的惟一索引或主鍵值重複,則會引起重複鍵錯誤,語句將停止。使用 IGNORE,將丟棄該行,不會報錯。忽略的錯誤會生成警告。   插入分區表時沒有找到與給定分區值匹配的值,IGNORE 也有相似的效果。沒有 IGNORE,這樣的 INSERT 語句將因錯誤而停止。使用 INSERT IGNORE 時,對於包含不匹配值的行,INSERT 操做將失敗而不報錯,但會插入匹配的行。   若是未指定 IGNORE,觸發錯誤的數據轉換將停止語句。使用 IGNORE,無效值將調整爲最接近的值並插入;將生成警告,但語句不會停止。可使用 mysql_info() C API 函數肯定表中實際插入了多少行。   ● 指定 ON DUPLICATE KEY UPDATE,若是插入的行會致使惟一索引或主鍵中出現重複值,則會更新舊行。若是將行做爲新行插入,則每行受影響的行值爲 1;若是更新現有行,則每行的受影響行值爲 2;若是將現有行設置爲當前值,則每行的受影響行值爲 0。若是在鏈接到 mysqld 時將CLIENT_FOUND_ROWS 標誌指定給 mysql_real_connect() C API 函數,則若是將現有行設置爲其當前值,則受影響的行值爲 1(而不是0)。   ● INSERT DELAYED 在 MySQL 5.6 中被棄用,並計劃最終刪除。在MySQL 8.0 中,接受 DELAYED 修飾符,但實際不起做用。使用INSERT(無 DELAYED)代替。
相關文章
相關標籤/搜索