文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (美國信紙尺寸) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 參考手冊  /  ...  /  INSERT 語法

15.2.7 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)] ... }
    [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 ... VALUESINSERT ... VALUES ROW()INSERT ... SET 等形式會根據明確指定的值插入列。INSERT ... SELECT 形式則會從另一個或多個資料表中選取列並插入。您也可以使用 INSERT ... TABLE 從單一資料表中插入列。具有 ON DUPLICATE KEY UPDATE 子句的 INSERT 允許在要插入的列於 UNIQUE 索引或 PRIMARY KEY 中產生重複值時,更新現有列。搭配 ON DUPLICATE KEY UPDATE 時,可以使用包含一或多個可選欄別名的列別名來參考要插入的列。

關於 INSERT ... SELECTINSERT ... 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 ... VALUESINSERT ... 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' 插入 INTFLOATDECIMAL(10,6)YEAR 欄位,分別會插入值 199919.992119.9921001999INTYEAR 欄位中儲存的值為 1999,因為字串到數字的轉換只會查看字串的初始部分,而該部分可能會被視為有效的整數或年份。對於 FLOATDECIMAL 欄位,字串到數字的轉換會將整個字串視為有效的數值。

  • 運算式 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 ... VALUESINSERT ... VALUES ROW() 搭配多個數值列表,或者 INSERT ... SELECTINSERT ... 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

  • 將超過欄位最大長度的字串插入字串欄位 (CHARVARCHARTEXTBLOB)。該值會被截斷為欄位的最大長度。

  • 將對於資料類型而言不合法的數值插入日期或時間欄位。該欄位會設定為該類型的適當零值。

  • 對於涉及 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 僅影響僅使用資料表層級鎖定的儲存引擎 (例如 MyISAMMEMORYMERGE)。

    注意

    LOW_PRIORITY 通常不應與 MyISAM 資料表一起使用,因為這樣做會停用並行插入。請參閱 第 10.11.3 節「並行插入」

  • 如果您指定 HIGH_PRIORITY,則會覆寫伺服器以該選項啟動時 --low-priority-updates 選項的效果。它也會導致不使用並行插入。請參閱 第 10.11.3 節「並行插入」

    HIGH_PRIORITY 僅影響僅使用資料表層級鎖定的儲存引擎 (例如 MyISAMMEMORYMERGE)。

  • 如果您使用 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 來覆寫舊列。REPLACEINSERT 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 敘述」