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
從單一資料表中插入列。具有 ON DUPLICATE KEY UPDATE
子句的 INSERT
允許在要插入的列於 UNIQUE
索引或 PRIMARY KEY
中產生重複值時,更新現有列。搭配 ON DUPLICATE KEY UPDATE
時,可以使用包含一或多個可選欄別名的列別名來參考要插入的列。
關於 INSERT ... SELECT
和 INSERT ... ON DUPLICATE KEY UPDATE
的詳細資訊,請參閱 第 15.2.7.1 節,「INSERT ... SELECT Statement」 和 第 15.2.7.2 節,「INSERT ... ON DUPLICATE KEY UPDATE Statement」。
在 MySQL 8.4 中,DELAYED
關鍵字會被接受,但伺服器會忽略它。關於此情況的原因,請參閱 第 15.2.7.3 節,「INSERT DELAYED Statement」。
要插入資料至資料表,需要該資料表的 INSERT
權限。如果使用 ON DUPLICATE KEY UPDATE
子句,且重複的索引鍵導致執行 UPDATE
,則該陳述式需要更新欄位的 UPDATE
權限。對於讀取但不修改的欄位,您只需要 SELECT
權限(例如,僅在 ON DUPLICATE KEY UPDATE
子句中的 col_name
=expr
指定的右側參考的欄位)。
當插入分割資料表時,您可以控制哪些分割區和子分割區接受新的列。PARTITION
子句會使用以逗號分隔的資料表一或多個分割區或子分割區(或兩者)的名稱清單。如果給定 INSERT
陳述式要插入的任何列不符合所列出的分割區之一,則 INSERT
陳述式會失敗並顯示錯誤訊息:Found a row not matching the given partition set。如需更多資訊和範例,請參閱 第 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);
可以使用 ROW_COUNT()
SQL 函數或 mysql_affected_rows()
C API 函數來取得 INSERT
的受影響列值。請參閱 第 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
中有重複值,則會更新舊列。如果該列是做為新列插入,則每列的受影響列數值為 1;如果更新現有列,則為 2;如果現有列設定為其目前值,則為 0。如果在連線至 mysqld 時,您對mysql_real_connect()
C API 函式指定了CLIENT_FOUND_ROWS
旗標,則如果現有列設定為其目前值,則受影響的列數值為 1 (不是 0)。請參閱 第 15.2.7.2 節「INSERT ... ON DUPLICATE KEY UPDATE 敘述」。INSERT DELAYED
已在 MySQL 5.6 中被棄用,並計劃最終移除。在 MySQL 8.4 中,接受DELAYED
修飾詞,但會忽略它。請改用INSERT
(不含DELAYED
)。請參閱 第 15.2.7.3 節「INSERT DELAYED 敘述」。