文件首頁
MySQL 9.0 參考手冊
相關文件 下載本手冊
PDF (美式信紙) - 40.0Mb
PDF (A4) - 40.1Mb
Man Pages (TGZ) - 258.2Kb
Man Pages (Zip) - 365.3Kb
資訊 (Gzip) - 4.0Mb
資訊 (Zip) - 4.0Mb


MySQL 9.0 參考手冊  /  ...  /  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 從單一資料表插入資料列。INSERTON DUPLICATE KEY UPDATE 子句結合使用時,如果即將插入的資料列會在 UNIQUE 索引或 PRIMARY KEY 中造成重複值,則可以更新現有的資料列。可以使用一個或多個選用的欄位別名,將列別名與 ON DUPLICATE KEY UPDATE 搭配使用,以參照要插入的資料列。

如需有關 INSERT ... SELECTINSERT ... 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 ... 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);

對於 INSERT 語句,受影響的列數值可以使用 ROW_COUNT() SQL 函數或 mysql_affected_rows() C API 函數取得。請參閱 第 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 中導致重複值,則會發生舊列的 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 語句」