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)] ... }
[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] ...)]
SET assignment_list
[AS row_alias[(col_alias [, col_alias] ...)]]
[ON DUPLICATE KEY UPDATE assignment_list]
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
[PARTITION (partition_name [, partition_name] ...)]
[(col_name [, col_name] ...)]
{ SELECT ...
| TABLE table_name
| VALUES row_constructor_list
}
[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 =
value
| [row_alias.]col_name
| [tbl_name.]col_name
| [row_alias.]col_alias
assignment_list:
assignment [, assignment] ...
INSERT
將新的資料列插入到現有的資料表中。INSERT ... VALUES
、INSERT ... VALUES ROW()
和 INSERT ... SET
等形式的陳述式會根據明確指定的值插入資料列。INSERT ... SELECT
形式會插入從另一個或多個資料表選取的資料列。您也可以使用 INSERT ... TABLE
從單一資料表插入資料列。INSERT
與 ON DUPLICATE KEY UPDATE
子句結合使用時,如果即將插入的資料列會在 UNIQUE
索引或 PRIMARY KEY
中造成重複值,則可以更新現有的資料列。可以使用一個或多個選用的欄位別名,將列別名與 ON DUPLICATE KEY UPDATE
搭配使用,以參照要插入的資料列。
如需有關 INSERT ... SELECT
和 INSERT ... ON DUPLICATE KEY UPDATE
的其他資訊,請參閱章節 15.2.7.1,「INSERT ... SELECT 陳述式」 和 章節 15.2.7.2,「INSERT ... ON DUPLICATE KEY UPDATE 陳述式」。
在 MySQL 9.0 中,伺服器會接受 DELAYED
關鍵字,但會忽略該關鍵字。有關其原因,請參閱 章節 15.2.7.3,「INSERT DELAYED 陳述式」。
將資料插入資料表需要該資料表的 INSERT
權限。如果使用了 ON DUPLICATE KEY UPDATE
子句,且重複鍵導致執行 UPDATE
,則陳述式需要更新欄位的 UPDATE
權限。對於已讀取但未修改的欄位,您只需要 SELECT
權限(例如,僅在 ON DUPLICATE KEY UPDATE
子句中 col_name
=expr
指派的右側參照的欄位)。
當插入分割區資料表時,您可以控制哪些分割區和子分割區接受新的資料列。PARTITION
子句採用資料表的一個或多個分割區或子分割區(或兩者)的逗號分隔名稱清單。如果給定 INSERT
陳述式所插入的任何資料列與所列的其中一個分割區不符,則 INSERT
陳述式會失敗,並顯示錯誤訊息 找到與給定的分割區集不符的資料列。如需更多資訊和範例,請參閱章節 26.5,「分割區選擇」。
tbl_name
是應該插入資料列的資料表。指定陳述式提供值的欄位,如下所示:
在資料表名稱後方提供括號內的逗號分隔欄位名稱清單。在這種情況下,必須由
VALUES
清單、VALUES ROW()
清單或SELECT
陳述式提供每個已命名欄位的值。對於INSERT TABLE
形式,來源資料表中的欄位數必須與要插入的欄位數一致。如果您未指定
INSERT ... VALUES
或INSERT ... SELECT
的欄位名稱清單,則資料表中每個欄位的值必須由VALUES
清單、SELECT
陳述式或TABLE
陳述式提供。如果您不知道資料表中欄位的順序,請使用DESCRIBE
來找出。tbl_name
SET
子句會明確地依名稱指示欄位,以及指派給每個欄位的值。
欄位值可以透過幾種方式給定:
如果未啟用嚴格 SQL 模式,則任何未明確給定值的欄位都會設定為其預設值(明確或隱含)。例如,如果您指定的欄位清單未命名資料表中的所有欄位,則未命名的欄位會設定為其預設值。預設值指派說明於 章節 13.6,「資料類型預設值」。
如果啟用嚴格 SQL 模式,
INSERT
陳述式如果未指定每個沒有預設值的欄位的明確值,則會產生錯誤。請參閱 章節 7.1.11,「伺服器 SQL 模式」。如果欄位清單和
VALUES
清單皆為空白,則INSERT
會建立一個資料列,其中每個欄位都設定為其預設值。INSERT INTO tbl_name () VALUES();
如果未啟用嚴格模式,MySQL 會對任何沒有明確定義預設值的欄位使用隱含預設值。如果啟用嚴格模式,則如果任何欄位沒有預設值,就會發生錯誤。
使用關鍵字
DEFAULT
將欄位明確設定為其預設值。這讓編寫INSERT
陳述式更容易,這些陳述式會將值指派給除了少數幾個欄位以外的所有欄位,因為這讓您可以避免編寫不完整的VALUES
清單,其中不包含資料表中每個欄位的值。否則,您必須提供與VALUES
清單中每個值對應的欄位名稱清單。如果明確插入產生的欄位,則唯一允許的值為
DEFAULT
。如需有關產生欄位的資訊,請參閱 章節 15.1.20.8,「CREATE TABLE 和產生欄位」。在運算式中,您可以使用
DEFAULT(
來產生欄位col_name
)col_name
的預設值。如果運算式資料類型與欄位資料類型不符,可能會發生提供欄位值的運算式
expr
的類型轉換。給定值的轉換可能會根據欄位類型產生不同的插入值。例如,將字串'1999.0e-2'
插入INT
、FLOAT
、DECIMAL(10,6)
或YEAR
欄位,會分別插入值1999
、19.9921
、19.992100
或1999
。INT
和YEAR
欄位中儲存的值為1999
,因為字串轉數字的轉換只會檢視字串初始部分中可以視為有效整數或年份的部分。對於FLOAT
和DECIMAL
欄位,字串轉數字的轉換會將整個字串視為有效數值。運算式
expr
可以參照值清單中先前設定的任何欄位。例如,您可以這樣做,因為col2
的值會參照先前已指派的col1
。INSERT INTO tbl_name (col1,col2) VALUES(15,col1*2);
但以下是不合法的,因為
col1
的值會參照在col1
之後指派的col2
。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);
每個值清單都必須包含與每個資料列要插入的完全一樣多的值。下列陳述式無效,因為它包含一個包含九個值的清單,而不是三個包含三個值的清單。
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);
對於 INSERT
語句,受影響的列數值可以使用 ROW_COUNT()
SQL 函數或 mysql_affected_rows()
C API 函數取得。請參閱 第 14.15 節「資訊函數」,以及 mysql_affected_rows()。
如果您使用帶有多個值列表的 INSERT ... VALUES
或 INSERT ... VALUES ROW()
,或是 INSERT ... SELECT
或 INSERT ... TABLE
,該語句將會返回以下格式的資訊字串:
Records: N1 Duplicates: N2 Warnings: N3
如果您使用的是 C API,可以透過呼叫 mysql_info()
函數取得資訊字串。請參閱 mysql_info()。
Records
表示該語句處理的列數。(這不一定是實際插入的列數,因為 Duplicates
可能不是零。)Duplicates
表示由於重複現有唯一索引值而無法插入的列數。Warnings
表示嘗試插入在某些方面有問題的欄位值的次數。在以下任何條件下都可能發生警告:
將
NULL
插入已宣告為NOT NULL
的欄位。對於多列INSERT
語句或INSERT INTO ... SELECT
語句,該欄位會設定為該欄位資料類型的隱含預設值。對於數值類型,它是0
;對於字串類型,它是空字串 (''
);對於日期和時間類型,它是「零」值。INSERT INTO ... SELECT
語句的處理方式與多列插入相同,因為伺服器不會檢查SELECT
的結果集,以查看它是否返回單一列。(對於單列INSERT
,當NULL
插入NOT NULL
欄位時,不會發生警告。而是語句會失敗並顯示錯誤。)將數值欄位設定為超出欄位範圍的值。該值會被截斷到範圍的最接近端點。
將例如
'10.34 a'
的值指派給數值欄位。尾隨的非數值文字會被移除,並插入剩餘的數值部分。如果字串值沒有前導數值部分,則該欄位會設定為0
。將字串插入到字串欄位(
CHAR
、VARCHAR
、TEXT
或BLOB
)中,該字串超出欄位的最大長度。該值會被截斷為欄位的最大長度。將對於資料類型不合法的數值插入到日期或時間欄位中。該欄位會被設定為該類型適當的零值。
有關涉及
AUTO_INCREMENT
欄位值的INSERT
範例,請參閱 第 5.6.9 節「使用 AUTO_INCREMENT」。如果
INSERT
將列插入到具有AUTO_INCREMENT
欄位的表格中,您可以使用LAST_INSERT_ID()
SQL 函數或mysql_insert_id()
C API 函數來找到該欄位使用的值。注意這兩個函數的行為並不總是一致的。
INSERT
語句關於AUTO_INCREMENT
欄位的行為在 第 14.15 節「資訊函數」和 mysql_insert_id() 中有進一步的討論。
INSERT
語句支援以下修飾詞:
如果您使用
LOW_PRIORITY
修飾詞,則會延遲執行INSERT
,直到沒有其他用戶端從該表格讀取資料為止。這包括其他在現有用戶端讀取時開始讀取的用戶端,以及INSERT LOW_PRIORITY
語句正在等待時的用戶端。因此,發出INSERT LOW_PRIORITY
語句的用戶端可能會等待很長一段時間。LOW_PRIORITY
只會影響僅使用表格層級鎖定的儲存引擎(例如MyISAM
、MEMORY
和MERGE
)。注意LOW_PRIORITY
通常不應與MyISAM
表格一起使用,因為這樣做會停用並行插入。請參閱 第 10.11.3 節「並行插入」。如果您指定
HIGH_PRIORITY
,它會覆寫如果伺服器啟動時帶有該選項,--low-priority-updates
選項的效果。它也會導致不使用並行插入。請參閱 第 10.11.3 節「並行插入」。HIGH_PRIORITY
只會影響僅使用表格層級鎖定的儲存引擎(例如MyISAM
、MEMORY
和MERGE
)。如果您使用
IGNORE
修飾詞,則會忽略執行INSERT
語句時發生的可忽略錯誤。例如,如果沒有IGNORE
,則在表格中重複現有UNIQUE
索引或PRIMARY KEY
值的列會導致重複鍵錯誤,並且語句會中止。使用IGNORE
,該列會被捨棄,並且不會發生錯誤。忽略的錯誤會產生警告。IGNORE
對於插入到找不到符合特定值的分割表格中具有類似的效果。如果沒有IGNORE
,此類INSERT
語句會中止並顯示錯誤。當使用INSERT IGNORE
時,對於包含不符合的值的列,插入作業會靜默失敗,但會插入符合的列。有關範例,請參閱 第 26.2.2 節「LIST 分割」。如果沒有指定
IGNORE
,則會中止會觸發錯誤的資料轉換。使用IGNORE
時,會將無效值調整為最接近的值並插入;會產生警告,但語句不會中止。您可以使用mysql_info()
C API 函數來判斷實際插入表格中的列數。如需更多資訊,請參閱 IGNORE 對於語句執行的影響。
您可以使用
REPLACE
而不是INSERT
來覆寫舊列。REPLACE
與INSERT IGNORE
在處理包含重複舊列的唯一鍵值的新列時是對應的:新列會取代舊列,而不是被捨棄。請參閱 第 15.2.12 節「REPLACE 語句」。如果您指定
ON DUPLICATE KEY UPDATE
,並且插入的列會在UNIQUE
索引或PRIMARY KEY
中導致重複值,則會發生舊列的UPDATE
。如果列作為新列插入,則每列的受影響列數值為 1;如果更新現有的列,則為 2;如果將現有列設定為其目前的值,則為 0。如果您在連接到 mysqld 時,將CLIENT_FOUND_ROWS
旗標指定給mysql_real_connect()
C API 函數,則如果將現有列設定為其目前的值,則受影響列的數值為 1(而不是 0)。請參閱 第 15.2.7.2 節「INSERT ... ON DUPLICATE KEY UPDATE 語句」。INSERT DELAYED
已在 MySQL 5.6 中棄用,並計劃最終移除。在 MySQL 9.0 中,接受但忽略DELAYED
修飾詞。請改用INSERT
(不含DELAYED
)。請參閱 第 15.2.7.3 節「INSERT DELAYED 語句」。