文件首頁
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 參考手冊  /  ...  /  LOAD DATA 陳述式

15.2.9 LOAD DATA 陳述式

LOAD DATA
    [LOW_PRIORITY | CONCURRENT] [LOCAL]
    INFILE 'file_name'
    [REPLACE | IGNORE]
    INTO TABLE tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [CHARACTER SET charset_name]
    [{FIELDS | COLUMNS}
        [TERMINATED BY 'string']
        [[OPTIONALLY] ENCLOSED BY 'char']
        [ESCAPED BY 'char']
    ]
    [LINES
        [STARTING BY 'string']
        [TERMINATED BY 'string']
    ]
    [IGNORE number {LINES | ROWS}]
    [(col_name_or_user_var
        [, col_name_or_user_var] ...)]
    [SET col_name={expr | DEFAULT}
        [, col_name={expr | DEFAULT}] ...]

LOAD DATA 陳述式會從文字檔案中讀取資料列,並以非常快的速度寫入資料表。檔案可以從伺服器主機或用戶端主機讀取,這取決於是否指定了 LOCAL 修飾詞。LOCAL 也會影響資料解譯和錯誤處理。

LOAD DATASELECT ... INTO OUTFILE 的補充。(請參閱 章節 15.2.13.1,「SELECT ... INTO Statement」。) 若要將資料從資料表寫入檔案,請使用 SELECT ... INTO OUTFILE。若要將檔案讀回資料表,請使用 LOAD DATAFIELDSLINES 子句的語法對於這兩種陳述式都相同。

mysqlimport 公用程式提供另一種載入資料檔案的方式;它的運作方式是將 LOAD DATA 陳述式傳送至伺服器。請參閱 章節 6.5.5,「mysqlimport — 資料匯入程式」

如需有關 INSERTLOAD DATA 的效率以及加速 LOAD DATA 的資訊,請參閱 章節 10.2.5.1,「最佳化 INSERT 陳述式」

非 LOCAL 與 LOCAL 操作

與非 LOCAL 操作相比,LOCAL 修飾詞會影響 LOAD DATA 的這些方面

只有在伺服器和您的用戶端都已設定為允許時,LOCAL 才會運作。例如,如果 mysqld 是在停用 local_infile 系統變數的情況下啟動,LOCAL 就會產生錯誤。請參閱章節 8.1.6,「LOAD DATA LOCAL 的安全性考量」

輸入檔案字元集

檔案名稱必須以常值字串提供。在 Windows 上,請將路徑名稱中的反斜線指定為正斜線或雙反斜線。伺服器會使用 character_set_filesystem 系統變數所指示的字元集來解譯檔案名稱。

根據預設,伺服器會使用 character_set_database 系統變數所指示的字元集來解譯檔案內容。如果檔案內容使用的字元集與此預設值不同,最好使用 CHARACTER SET 子句來指定該字元集。字元集 binary 指定為「不轉換」。

SET NAMEScharacter_set_client 的設定不會影響檔案內容的解譯。

LOAD DATA 會將檔案中的所有欄位解譯為具有相同的字元集,無論載入欄位值的欄位資料類型為何。為了正確解譯檔案,您必須確保它是以正確的字元集寫入的。例如,如果您使用 mysqldump -T 或在 mysql 中發出 SELECT ... INTO OUTFILE 陳述式來寫入資料檔案,請務必使用 --default-character-set 選項,以寫入當檔案使用 LOAD DATA 載入時要使用的字元集中的輸出。

注意

無法載入使用 ucs2utf16utf16leutf32 字元集的資料檔案。

輸入檔案位置

這些規則決定 LOAD DATA 輸入檔案位置

  • 如果未指定 LOCAL,檔案必須位於伺服器主機上。伺服器會直接讀取檔案,並以下列方式找到它

    • 如果檔案名稱是絕對路徑名稱,伺服器會按原樣使用它。

    • 如果檔案名稱是具有前導元件的相對路徑名稱,伺服器會尋找相對於其資料目錄的檔案。

    • 如果檔案名稱沒有前導元件,伺服器會在預設資料庫的資料庫目錄中尋找該檔案。

  • 如果指定了 LOCAL,檔案必須位於用戶端主機上。用戶端程式會讀取檔案,並以下列方式找到它

    • 如果檔案名稱是絕對路徑名稱,用戶端程式會按原樣使用它。

    • 如果檔案名稱是相對路徑名稱,用戶端程式會尋找相對於其叫用目錄的檔案。

    使用 LOCAL 時,用戶端程式會讀取檔案並將其內容傳送至伺服器。伺服器會在儲存暫存檔案的目錄中建立檔案的複本。請參閱章節 B.3.3.5,「MySQL 儲存暫存檔案的位置」。如果此目錄中沒有足夠的空間來存放複本,可能會導致 LOAD DATA LOCAL 陳述式失敗。

LOCAL 規則表示伺服器會讀取相對於其資料目錄的 ./myfile.txt 檔案,而它會從預設資料庫的資料庫目錄中讀取名為 myfile.txt 的檔案。例如,如果在 db1 是預設資料庫時執行下列 LOAD DATA 陳述式,即使陳述式明確地將檔案載入 db2 資料庫中的資料表,伺服器也會從 db1 的資料庫目錄中讀取檔案 data.txt

LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table;
注意

伺服器也會使用非 LOCAL 規則來尋找 IMPORT TABLE 陳述式的 .sdi 檔案。

安全性需求

對於非 LOCAL 載入操作,伺服器會讀取位於伺服器主機上的文字檔案,因此必須滿足這些安全性需求

對於 LOCAL 載入操作,用戶端程式會讀取位於用戶端主機上的文字檔案。由於檔案內容是透過用戶端與伺服器的連線傳送,因此使用 LOCAL 會比伺服器直接存取檔案慢一些。另一方面,您不需要 FILE 權限,而且檔案可以位於用戶端程式可以存取的任何目錄中。

重複索引鍵和錯誤處理

REPLACEIGNORE 修飾詞會控制處理在唯一索引鍵值 (PRIMARY KEYUNIQUE 索引值) 上重複現有資料表列的新 (輸入) 列

LOCAL 修飾詞與 IGNORE 具有相同的效果。發生這種情況是因為伺服器無法在操作中間停止檔案傳輸。

如果未指定 REPLACEIGNORELOCAL 中的任何一個,則在找到重複的索引鍵值時會發生錯誤,並且會忽略文字檔案的其餘部分。

除了會如上所述影響重複索引鍵處理之外,IGNORELOCAL 也會影響錯誤處理

  • 如果沒有 IGNORE 也沒有 LOCAL,資料解譯錯誤會終止操作。

  • 使用 IGNORELOCAL 時,資料解譯錯誤會變成警告,並且載入操作會繼續,即使 SQL 模式是限制性的。如需範例,請參閱欄位值指派

索引處理

若要在載入操作期間忽略外鍵約束,請在執行 LOAD DATA 之前,執行 SET foreign_key_checks = 0 陳述式。

如果在空的 MyISAM 資料表上使用 LOAD DATA,所有非唯一索引都會在獨立的批次中建立(如同 REPAIR TABLE)。一般來說,當您有很多索引時,這會讓 LOAD DATA 快得多。在某些極端情況下,您可以使用 ALTER TABLE ... DISABLE KEYS 在將檔案載入資料表之前關閉索引,並在載入檔案後使用 ALTER TABLE ... ENABLE KEYS 重新建立索引,這樣可以更快地建立索引。請參閱 第 10.2.5.1 節「最佳化 INSERT 陳述式」

欄位和行處理

對於 LOAD DATASELECT ... INTO OUTFILE 陳述式,FIELDSLINES 子句的語法是相同的。這兩個子句都是可選的,但如果兩個都指定,FIELDS 必須在 LINES 之前。

如果您指定 FIELDS 子句,它的每個子子句(TERMINATED BY[OPTIONALLY] ENCLOSED BYESCAPED BY)也是可選的,但您必須至少指定其中一個。這些子句的引數只允許包含 ASCII 字元。

如果您沒有指定 FIELDSLINES 子句,則預設值與您寫下此程式碼時相同

FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'
LINES TERMINATED BY '\n' STARTING BY ''

在 SQL 陳述式中的字串中,反斜線是 MySQL 的跳脫字元。因此,若要指定一個字面反斜線,您必須指定兩個反斜線,該值才會被解譯為單一反斜線。跳脫序列 '\t''\n' 分別指定 Tab 和換行字元。

換句話說,預設值會導致 LOAD DATA 在讀取輸入時,作用如下

  • 在換行符號處尋找行界限。

  • 不跳過任何行首碼。

  • 在 Tab 字元處將行分割成欄位。

  • 不預期欄位會被任何引號字元括起來。

  • 將跳脫字元 \ 後面的字元解譯為跳脫序列。例如,\t\n\\ 分別表示 Tab、換行和反斜線。如需跳脫序列的完整清單,請參閱稍後關於 FIELDS ESCAPED BY 的討論。

相反地,預設值會導致 SELECT ... INTO OUTFILE 在寫入輸出時,作用如下

  • 在欄位之間寫入 Tab 字元。

  • 不將欄位括在任何引號字元內。

  • 使用 \ 來跳脫欄位值中出現的 Tab、換行或 \ 實例。

  • 在行尾寫入換行符號。

注意

對於在 Windows 系統上產生的文字檔案,正確的檔案讀取可能需要 LINES TERMINATED BY '\r\n',因為 Windows 程式通常使用兩個字元作為行終止符。某些程式(例如 WordPad)在寫入檔案時可能會使用 \r 作為行終止符。若要讀取這類檔案,請使用 LINES TERMINATED BY '\r'

如果所有輸入行都有您想要忽略的通用首碼,您可以使用 LINES STARTING BY 'prefix_string' 來跳過首碼及其之前的所有內容。如果某行不包含首碼,則會跳過整行。假設您發出以下陳述式

LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test
  FIELDS TERMINATED BY ','  LINES STARTING BY 'xxx';

如果資料檔案看起來像這樣

xxx"abc",1
something xxx"def",2
"ghi",3

產生的列為 ("abc",1)("def",2)。檔案中的第三行會被跳過,因為它不包含首碼。

可以使用 IGNORE number LINES 子句來忽略檔案開頭的行。例如,您可以使用 IGNORE 1 LINES 來跳過包含欄名稱的初始標題行

LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test IGNORE 1 LINES;

當您結合使用 SELECT ... INTO OUTFILELOAD DATA,以將資料從資料庫寫入檔案,然後稍後將檔案讀回資料庫時,兩個陳述式的欄位和行處理選項必須相符。否則,LOAD DATA 無法正確解譯檔案的內容。假設您使用 SELECT ... INTO OUTFILE 來寫入以逗號分隔欄位的檔案

SELECT * INTO OUTFILE 'data.txt'
  FIELDS TERMINATED BY ','
  FROM table2;

若要讀取以逗號分隔的檔案,正確的陳述式為

LOAD DATA INFILE 'data.txt' INTO TABLE table2
  FIELDS TERMINATED BY ',';

相反地,如果您嘗試使用以下顯示的陳述式來讀取檔案,則它將無法運作,因為它指示 LOAD DATA 在欄位之間尋找 Tab 字元

LOAD DATA INFILE 'data.txt' INTO TABLE table2
  FIELDS TERMINATED BY '\t';

可能結果是每行輸入都會被解譯為單一欄位。

LOAD DATA 可用於讀取從外部來源取得的檔案。例如,許多程式可以匯出逗號分隔值 (CSV) 格式的資料,以便讓行的欄位以逗號分隔並括在雙引號內,且第一行包含欄名稱。如果這類檔案中的行是以歸位字元/換行字元對終止,則此處顯示的陳述式說明您將用來載入檔案的欄位和行處理選項

LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name
  FIELDS TERMINATED BY ',' ENCLOSED BY '"'
  LINES TERMINATED BY '\r\n'
  IGNORE 1 LINES;

如果輸入值不一定括在引號內,請在 ENCLOSED BY 選項之前使用 OPTIONALLY

任何欄位或行處理選項都可以指定空字串 ('')。如果不是空的,FIELDS [OPTIONALLY] ENCLOSED BYFIELDS ESCAPED BY 值必須是單一字元。FIELDS TERMINATED BYLINES STARTING BYLINES TERMINATED BY 值可以超過一個字元。例如,若要寫入以歸位字元/換行字元對終止的行,或讀取包含這類行的檔案,請指定 LINES TERMINATED BY '\r\n' 子句。

若要讀取包含以由 %% 組成的行分隔的笑話的檔案,您可以執行此動作

CREATE TABLE jokes
  (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  joke TEXT NOT NULL);
LOAD DATA INFILE '/tmp/jokes.txt' INTO TABLE jokes
  FIELDS TERMINATED BY ''
  LINES TERMINATED BY '\n%%\n' (joke);

FIELDS [OPTIONALLY] ENCLOSED BY 控制欄位的引號。對於輸出 (SELECT ... INTO OUTFILE),如果您省略單字 OPTIONALLY,則所有欄位都會以 ENCLOSED BY 字元括起來。此處顯示此類輸出的範例(使用逗號作為欄位分隔符號)

"1","a string","100.20"
"2","a string containing a , comma","102.20"
"3","a string containing a \" quote","102.20"
"4","a string containing a \", quote and comma","102.20"

如果您指定 OPTIONALLY,則 ENCLOSED BY 字元僅用於括起具有字串資料類型(例如 CHARBINARYTEXTENUM)的欄位值

1,"a string",100.20
2,"a string containing a , comma",102.20
3,"a string containing a \" quote",102.20
4,"a string containing a \", quote and comma",102.20

欄位值中出現的 ENCLOSED BY 字元會加上 ESCAPED BY 字元作為前置詞來跳脫。此外,如果您指定空的 ESCAPED BY 值,則可能會無意中產生無法被 LOAD DATA 正確讀取的輸出。例如,如果跳脫字元為空的,則剛才顯示的先前輸出會如下所示。請注意,第四行中的第二個欄位在引號後面包含逗號,這(錯誤地)顯示終止了欄位

1,"a string",100.20
2,"a string containing a , comma",102.20
3,"a string containing a " quote",102.20
4,"a string containing a ", quote and comma",102.20

對於輸入,ENCLOSED BY 字元(如果存在)會從欄位值的末端剝除。(無論是否指定 OPTIONALLY,都是如此;OPTIONALLY 對輸入解譯沒有影響。)以 ESCAPED BY 字元為前置詞的 ENCLOSED BY 字元出現的情況會被解譯為目前欄位值的一部分。

如果欄位以 ENCLOSED BY 字元開頭,則僅當該字元後接欄位或行 TERMINATED BY 序列時,才會將該字元的實例識別為終止欄位值。為了避免模稜兩可,欄位值中出現的 ENCLOSED BY 字元可以加倍,並解譯為該字元的單一實例。例如,如果指定 ENCLOSED BY '"',則會如下所示處理引號

"The ""BIG"" boss"  -> The "BIG" boss
The "BIG" boss      -> The "BIG" boss
The ""BIG"" boss    -> The ""BIG"" boss

FIELDS ESCAPED BY 控制如何讀取或寫入特殊字元

  • 對於輸入,如果 FIELDS ESCAPED BY 字元不是空的,則會剝除該字元的實例,並且以下字元會按字面解釋為欄位值的一部分。有些雙字元序列是例外,其中第一個字元是跳脫字元。這些序列顯示在下表中(使用 \ 作為跳脫字元)。NULL 處理的規則會在稍後於本節中說明。

    字元 跳脫序列
    \0 ASCII NUL (X'00') 字元
    \b 倒退鍵字元
    \n 換行(換行)字元
    \r 歸位字元
    \t 一個 Tab 字元。
    \Z ASCII 26 (Control+Z)
    \N NULL

    關於 \ 跳脫語法的更多資訊,請參閱第 11.1.1 節「字串文字」

    如果 FIELDS ESCAPED BY 字元為空,則不會發生跳脫序列解譯。

  • 對於輸出,如果 FIELDS ESCAPED BY 字元不為空,則它會用於在輸出時為以下字元加上前綴

    • FIELDS ESCAPED BY 字元。

    • FIELDS [OPTIONALLY] ENCLOSED BY 字元。

    • 如果 ENCLOSED BY 字元為空或未指定,則為 FIELDS TERMINATED BYLINES TERMINATED BY 值的第一個字元。

    • ASCII 0(實際上在跳脫字元之後寫入的是 ASCII 0,而不是零值位元組)。

    如果 FIELDS ESCAPED BY 字元為空,則不會跳脫任何字元,且 NULL 會輸出為 NULL,而不是 \N。指定一個空的跳脫字元可能不是一個好主意,尤其是當您資料中的欄位值包含剛剛給出的清單中的任何字元時。

在某些情況下,欄位和行處理選項會相互影響

  • 如果 LINES TERMINATED BY 是空字串,且 FIELDS TERMINATED BY 非空,則行也會以 FIELDS TERMINATED BY 終止。

  • 如果 FIELDS TERMINATED BYFIELDS ENCLOSED BY 的值都為空 ( '' ),則會使用固定行 (非分隔) 格式。使用固定行格式時,欄位之間不會使用分隔符號 (但您仍然可以有行終止符號)。相反地,會使用足以容納欄位中所有值的欄位寬度來讀取和寫入欄位值。對於TINYINTSMALLINTMEDIUMINTINTBIGINT,欄位寬度分別為 4、6、8、11 和 20,無論宣告的顯示寬度為何。

    LINES TERMINATED BY 仍然用於分隔行。如果某一行不包含所有欄位,則其餘的欄會設定為其預設值。如果您沒有行終止符號,您應該將其設定為 ''。在這種情況下,文字檔案必須包含每一列的所有欄位。

    固定行格式也會影響 NULL 值的處理,如後所述。

    注意

    如果您正在使用多位元組字元集,則固定大小的格式將無法運作。

NULL 值的處理會根據使用的 FIELDSLINES 選項而有所不同

  • 對於預設的 FIELDSLINES 值,NULL 在輸出時會寫成 \N 的欄位值,而 \N 的欄位值在輸入時會讀取為 NULL(假設 ESCAPED BY 字元為 \)。

  • 如果 FIELDS ENCLOSED BY 不為空,則包含文字單字 NULL 作為其值的欄位會讀取為 NULL 值。這與包含在 FIELDS ENCLOSED BY 字元內的單字 NULL 不同,後者會讀取為字串 'NULL'

  • 如果 FIELDS ESCAPED BY 為空,NULL 會寫成單字 NULL

  • 使用固定行格式 (當 FIELDS TERMINATED BYFIELDS ENCLOSED BY 都為空時使用),NULL 會寫為空字串。這會導致寫入檔案時,表格中的 NULL 值和空字串無法區分,因為兩者都會寫為空字串。如果您需要在讀取檔案時能夠區分兩者,則不應使用固定行格式。

根據欄位值指派中描述的規則,嘗試將 NULL 載入 NOT NULL 欄位會產生警告或錯誤。

LOAD DATA 不支援某些情況

  • 固定大小的行(FIELDS TERMINATED BYFIELDS ENCLOSED BY 都為空)以及 BLOBTEXT 欄位。

  • 如果您指定一個與另一個相同或以另一個為前綴的分隔符號,則 LOAD DATA 無法正確解譯輸入。例如,以下 FIELDS 子句會導致問題

    FIELDS TERMINATED BY '"' ENCLOSED BY '"'
  • 如果 FIELDS ESCAPED BY 為空,則包含 FIELDS ENCLOSED BYLINES TERMINATED BY 的出現,然後接續 FIELDS TERMINATED BY 值的欄位值,會導致 LOAD DATA 太早停止讀取欄位或行。之所以會發生這種情況,是因為 LOAD DATA 無法正確判斷欄位或行值的結尾位置。

欄位清單規格

以下範例會載入 persondata 表格的所有欄位

LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata;

預設情況下,如果在 LOAD DATA 語句結尾沒有提供欄位清單,則輸入行預期包含每個表格欄位的欄位。如果您只想載入表格的部分欄位,請指定欄位清單

LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata
(col_name_or_user_var [, col_name_or_user_var] ...);

如果輸入檔案中的欄位順序與表格中的欄位順序不同,您也必須指定欄位清單。否則,MySQL 無法判斷如何將輸入欄位與表格欄位比對。

輸入預處理

LOAD DATA 語法中的每個 col_name_or_user_var 執行個體都是欄位名稱或使用者變數。對於使用者變數,SET 子句可讓您在將結果指派給欄位之前,對其值執行預處理轉換。

SET 子句中的使用者變數有多種使用方式。以下範例直接使用第一個輸入欄作為 t1.column1 的值,並將第二個輸入欄指派給使用者變數,該使用者變數會先經過除法運算,然後再用於 t1.column2 的值

LOAD DATA INFILE 'file.txt'
  INTO TABLE t1
  (column1, @var1)
  SET column2 = @var1/100;

SET 子句可用於提供並非衍生自輸入檔案的值。以下語句會將 column3 設定為目前的日期和時間

LOAD DATA INFILE 'file.txt'
  INTO TABLE t1
  (column1, column2)
  SET column3 = CURRENT_TIMESTAMP;

您也可以將輸入值指派給使用者變數,而不將該變數指派給任何表格欄位,藉此捨棄該輸入值

LOAD DATA INFILE 'file.txt'
  INTO TABLE t1
  (column1, @dummy, column2, @dummy, column3);

欄位/變數清單和 SET 子句的使用受限於以下限制

  • SET 子句中的指派運算子左側應該只有欄位名稱。

  • 您可以在 SET 指派運算子的右側使用子查詢。傳回要指派給欄位的值的子查詢只能是純量子查詢。此外,您不能使用子查詢從正在載入的表格中選取。

  • IGNORE number LINES 子句忽略的行不會為欄位/變數清單或 SET 子句處理。

  • 使用固定行格式載入資料時,無法使用使用者變數,因為使用者變數沒有顯示寬度。

欄位值指派

為了處理輸入行,LOAD DATA 會將其分割成欄位,並根據欄位/變數清單和 SET 子句 (如果有的話) 使用這些值。然後,將產生的列插入到表格中。如果表格有 BEFORE INSERTAFTER INSERT 觸發程序,則會在插入列之前或之後分別啟動它們。

欄位值的解譯和指派給表格欄位取決於以下因素

  • SQL 模式(sql_mode 系統變數的值)。此模式可能是非限制性的,也可能是以各種方式限制性的。例如,可以啟用嚴格 SQL 模式,或者該模式可以包含諸如 NO_ZERO_DATENO_ZERO_IN_DATE 之類的值。

  • IGNORELOCAL 修飾符號的存在與否。

這些因素結合在一起會導致 LOAD DATA 進行限制性或非限制性的資料解譯

  • 如果 SQL 模式是限制性的,並且未指定 IGNORELOCAL 修飾符號,則資料解譯是限制性的。錯誤會終止載入作業。

  • 如果 SQL 模式是非限制性的,或者指定了 IGNORELOCAL 修飾符號,則資料解譯是非限制性的。(特別是,如果省略 REPLACE 修飾符號,則任何一個修飾符號(如果已指定)都會覆寫限制性 SQL 模式。)錯誤會變成警告,且載入作業會繼續。

限制性資料解譯會使用這些規則

  • 欄位過多或過少會導致錯誤。

  • NULL (即 \N) 指派給非 NULL 欄位會導致錯誤。

  • 超出欄位資料類型範圍的值會導致錯誤。

  • 無效值會產生錯誤。例如,數值欄位的值 (例如 'x') 會導致錯誤,而不是轉換為 0。

相反地,非限制性資料解譯會使用這些規則

  • 如果輸入行的欄位過多,則會忽略多餘的欄位,且警告數會遞增。

  • 如果輸入行欄位過少,則會將遺失的輸入欄位所對應的欄位指定為其預設值。預設值的指定方式在第 13.6 節「資料類型預設值」中有說明。

  • NULL (亦即 \N) 指定給非 NULL 欄位,會導致指定該欄位資料類型的隱含預設值。隱含預設值的說明在第 13.6 節「資料類型預設值」中。

  • 無效的值會產生警告而不是錯誤,並會轉換為欄位資料類型的最接近的有效值。範例:

    • 數值欄位的值(例如 'x')會轉換為 0。

    • 超出範圍的數值或時間值會被截斷為該欄位資料類型範圍的最接近端點。

    • 無論 SQL 模式 NO_ZERO_DATE 設定為何,DATETIMEDATETIME 欄位的無效值都會插入為隱含的預設值。隱含的預設值為該類型適當的值('0000-00-00 00:00:00''0000-00-00''00:00:00')。請參閱第 13.2 節「日期和時間資料類型」

  • LOAD DATA 解釋空欄位值的方式與遺失的欄位不同。

    • 對於字串類型,欄位會設定為空字串。

    • 對於數值類型,欄位會設定為 0

    • 對於日期和時間類型,欄位會設定為該類型適當的值。請參閱第 13.2 節「日期和時間資料類型」

    這些值與您在 INSERTUPDATE 陳述式中明確將空字串指定給字串、數值或日期或時間類型時所產生的值相同。

只有在欄位的值為 NULL(亦即 \N)且該欄位未宣告為允許 NULL 值,或者當 TIMESTAMP 欄位的預設值為目前的時間戳記,且在指定欄位清單時從欄位清單中省略時,才會將 TIMESTAMP 欄位設定為目前的日期和時間。

LOAD DATA 會將所有輸入視為字串,因此您無法像使用 INSERT 陳述式那樣,將數值用於 ENUMSET 欄位。所有的 ENUMSET 值都必須指定為字串。

無法使用二進位標記法(例如 b'011010')直接載入 BIT 值。為了解決這個問題,請使用 SET 子句來移除開頭的 b' 和結尾的 ',並執行從 2 進位到 10 進位的轉換,使 MySQL 將值正確載入 BIT 欄位。

$> cat /tmp/bit_test.txt
b'10'
b'1111111'
$> mysql test
mysql> LOAD DATA INFILE '/tmp/bit_test.txt'
       INTO TABLE bit_test (@var1)
       SET b = CAST(CONV(MID(@var1, 3, LENGTH(@var1)-3), 2, 10) AS UNSIGNED);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Deleted: 0  Skipped: 0  Warnings: 0

mysql> SELECT BIN(b+0) FROM bit_test;
+----------+
| BIN(b+0) |
+----------+
| 10       |
| 1111111  |
+----------+
2 rows in set (0.00 sec)

對於 0b 二進位標記法中的 BIT 值(例如 0b011010),請改用此 SET 子句來移除開頭的 0b

SET b = CAST(CONV(MID(@var1, 3, LENGTH(@var1)-2), 2, 10) AS UNSIGNED)

分割資料表支援

LOAD DATA 支援使用 PARTITION 子句明確選取分割區,其中包含一個或多個以逗號分隔的分割區、子分割區或兩者的名稱清單。當使用此子句時,如果檔案中的任何列都無法插入清單中命名的任何分割區或子分割區,則陳述式會失敗並顯示錯誤 找到與指定分割區集不符的列。如需更多資訊和範例,請參閱第 26.5 節「分割區選取」

並行考量

使用 LOW_PRIORITY 修飾詞,LOAD DATA 陳述式的執行會延遲,直到沒有其他用戶端從資料表中讀取資料為止。這只會影響僅使用資料表層級鎖定的儲存引擎(例如 MyISAMMEMORYMERGE)。

使用 CONCURRENT 修飾詞和滿足並行插入條件(亦即中間沒有空閒區塊)的 MyISAM 資料表,其他執行緒可以在 LOAD DATA 執行時從資料表中擷取資料。即使沒有其他執行緒同時使用資料表,此修飾詞也會稍微影響 LOAD DATA 的效能。

陳述式結果資訊

LOAD DATA 陳述式完成時,會以以下格式傳回資訊字串:

Records: 1  Deleted: 0  Skipped: 0  Warnings: 0

發生警告的情況與使用 INSERT 陳述式插入值時的情況相同(請參閱第 15.2.7 節「INSERT 陳述式」),但當輸入列中的欄位過少或過多時,LOAD DATA 也會產生警告。

您可以使用 SHOW WARNINGS 來取得前 max_error_count 個警告的清單,以取得有關錯誤原因的資訊。請參閱第 15.7.7.41 節「SHOW WARNINGS 陳述式」

如果您使用 C API,則可以呼叫 mysql_info() 函式來取得有關陳述式的資訊。請參閱mysql_info()

複寫考量

LOAD DATA 對於以陳述式為基礎的複寫而言,被認為是不安全的。如果您使用 LOAD DATA 搭配 binlog_format=STATEMENT,則每個要套用變更的複本都會建立一個包含資料的暫存檔案。即使來源啟用了二進位記錄加密,此暫存檔案也不會加密。如果需要加密,請改用以列為基礎或混合的二進位記錄格式,複本不會建立暫存檔案。如需有關 LOAD DATA 和複寫之間互動的更多資訊,請參閱第 19.5.1.19 節「複寫和 LOAD DATA」

其他主題

在 Unix 上,如果您需要 LOAD DATA 從管道讀取資料,您可以使用下列技巧(此範例將 / 目錄的清單載入到資料表 db1.t1 中):

mkfifo /mysql/data/db1/ls.dat
chmod 666 /mysql/data/db1/ls.dat
find / -ls > /mysql/data/db1/ls.dat &
mysql -e "LOAD DATA INFILE 'ls.dat' INTO TABLE t1" db1

在這裡,您必須在個別終端機上執行產生要載入資料的命令和 mysql 命令,或在背景中執行資料產生程序(如先前的範例所示)。如果您不這樣做,管道會被封鎖,直到 mysql 程序讀取資料為止。