LOAD DATA INFILE 语法
原文地址:http://blog.sina.com.cn/s/blog_539f03f00100xfxb.html
mysql 的LOAD DATA INFILE 是一個高速insert的不錯的方案 篇文章語法介紹的比較詳細,轉載,記錄。
其實我就這樣用:
load data infile '/home/mark/data_update.sql' replace into table test FIELDS TERMINATED BY ',' (id,name)?
terminate[英][?t?:mineit]
以后有機會說說,利用LOAD DATA INFILE進行批量更新、插入。
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name.txt' [REPLACE | IGNORE] INTO TABLE tbl_name [FIELDS [TERMINATED BY '\t'] [[OPTIONALLY] ENCLOSED BY ''] [ESCAPED BY '\\' ] ] [LINES TERMINATED BY '\n'] [IGNORE number LINES] [(col_name,...)]
LOAD DATA INFILE 語句以非常高的速度從一個文本文件中讀取記錄行并插入到一個表中。如果 LOCAL 關鍵詞被指定,文件從客戶端主機讀取。如果 LOCAL 沒有被指定,文件必須位于服務器上。由于安全性的原因,當讀取位于服務器端的文本文件時,文件必須處于數據庫目錄或可被所有人讀取的地方。同時,為了對服務器端的文件使用 LOAD DATA INFILE,你必須在服務器主機上有 FILE 權限。只有當你沒有以 --local-infile=0 選項啟動mysqld,或你沒有禁止你的客戶端程序支持 LOCAL的情況下,LOCAL 才會工作。查看章節,如果你指定關鍵詞LOW_PRIORITY,LOAD DATA 語句的執行將會被延遲,直到沒有其它的客戶端正在讀取表。
如果你對一個 MyISAM 表指定關鍵詞 CONCURRENT,那么當 LOAD DATA正在執行時,其它的線程仍可以從表中檢索數據。使用這個選項時,如果同時也有其它的線程正在使用表,這當然會有一點影響 LOAD DATA 的執行性能。
使用 LOCAL 將比讓服務器直接訪問文件要慢一些,因為文件的內容必須從客戶端主機傳送到服務器主機。而在另一方面,你不再需要有 FILE 權限用于裝載本地文件。
你也可以使用 mysqlimport 實用程序裝載數據文件;它通過發送一個 LOAD DATA INFILE 命令到服務器來動作。--local 選項使得 mysqlimport 從客戶端主機讀取數據文件。如果客戶端與服務器支持壓縮協議,你可以指定 --compress 選項,以在較慢的網絡中獲得更好的性能。
當從服務器主機定位文件時,服務器使用下列規則:
如果給定一個完整的路徑,服務器使用該路徑名。
如果給定一個有一個或多個前置構件的相對路徑,服務器以相對服務器的數據目錄搜索文件。
如果給定一個沒有前置構件的文件名,服務器從當前數據庫的數據庫目錄搜尋文件。
注意,這些規則意味著,一個以 `./myfile.txt' 給出的文件是從服務器的數據目錄中讀取的,然而,以`myfile.txt' 給出的一個文件是從當前數據庫的數據目錄下讀取的。舉例來說,下面的 LOAD DATA 語句從 db1數據庫目錄下讀取文件 `data.txt',因為 db1 是當前數據庫,即使該語句明確地指定讀取的文件被放入到 db2數據庫中的一個表中:
mysql> USE db1; mysql> LOAD DATA INFILE "data.txt" INTO TABLE db2.my_table;
REPLACE 和 IGNORE 關鍵詞控制對與現有的記錄在唯一鍵值上重復的記錄的處理。如果你指定 REPLACE,新的記錄行將替換有相同唯一鍵值的現有記錄行。如果你指定 IGNORE,將跳過與現有的記錄行在唯一鍵值上重復的輸入記錄行。如果你沒有指定任何一個選項,當重復鍵值出現時,將會發生一個錯誤,文本文件的剩余部分也將被忽略。
如果你使用 LOCAL 關鍵詞從一個本地文件中讀取數據,在此操作過程中,服務器沒有辦法停止文件的傳送,因此缺省的處理方式就好像是 IGNORE 被指定一樣。
如果你在一個空的 MyISAM 表上使用 LOAD DATA INFILE,所有非唯一索引會以一個分批方式被創建(就像REPAIR)。當有許多索引時,這通常可以使 LOAD DATA INFILE 更快一些。
LOAD DATA INFILE 的 SELECT ... INTO OUTFILE 的逆操作。使用 SELECT ... INTO OUTFILE 將數據從一個數據庫寫到一個文件中。使用 LOAD DATA INFILE 讀取文件到數據庫中。兩個命令的 FIELDS 和 LINES 子句的句法是一樣的。兩個子句都是可選的,但是如果兩個同時被指定,FIELDS 子句必須出現在 LINES 子句之前。
如果你指定一個 FIELDS 子句,它的子句 (TERMINATED BY、[OPTIONALLY] ENCLOSED BY 和 ESCAPED BY) 也是可選的,不過,你必須至少指定它們中的一個。
如果你沒有指定一個 FIELDS 子句,缺省的相同于如果你這樣寫:
FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'
如果你沒有指定一個 LINES 子句,缺省的相同于如果你這樣寫:
LINES TERMINATED BY '\n'
換句話說,當讀取輸入時,缺省值導致 LOAD DATA INFILE 表現如下:
在換行符處尋找行的邊界。
在定位符處將行分開放到字段中。
不認為字段由任何引號字符封裝。
將有 “\” 開頭的定位符、換行符或 `\' 解釋為字段值的一個文字字符。
相反的,當寫入輸出時,缺省值導致 SELECT ... INTO OUTFILE 表現如下:
在字段值間加上定位符。
不用任何引號字符封裝字段。
使用 “\” 轉義出現在字段值中的定位符、換行符或 `\' 字符實例。
在行的結尾處加上換行符。
注意,為了寫 FIELDS ESCAPED BY '\\',你必須指定兩個反斜線,該值會作為一個反斜線被讀入。
IGNORE number LINES 選項可被用于忽略文件開頭處的一個列名的頭:
mysql> LOAD DATA INFILE "/tmp/file_name" INTO TABLE test IGNORE 1 LINES;
當你一前一后地使用 SELECT ... INTO OUTFILE 和 LOAD DATA INFILE 將數據從一個數據庫寫到一個文件中,然后再從文件中將它讀入數據庫中時,兩個命令的字段和行處理選項必須匹配。否則,LOAD DATA INFILE 將不能正確地解釋文件內容。假設你使用 SELECT ... INTO OUTFILE 以逗號分隔字段的方式將數據寫入到一個文件中:
mysql> SELECT * INTO OUTFILE 'data.txt' -> FIELDS TERMINATED BY ',' -> FROM ...;
為了將由逗號分隔的文件讀回時,正確的語句應該是:
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE table2 -> FIELDS TERMINATED BY ',';
如果你試圖用下面所示的語句讀取文件,它將不會工作,因為命令 LOAD DATA INFILE 以定位符區分字段值:
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE table2 -> FIELDS TERMINATED BY '\t';
可能的結果是每個輸入行將被解釋為一個單獨的字段。
LOAD DATA INFILE 也可以被用來讀取從外部來源獲得的文件。例如,dBASE 格式的文件,字段以逗號分隔并以雙引號包圍著。如果文件中的行以一個換行符終止,那么下面所示的可以說明你將用來裝載文件的字段和行處理選項:
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name -> FIELDS TERMINATED BY ',' ENCLOSED BY '"' -> LINES TERMINATED BY '\n';
任何字段和行處理選項都可以指定一個空字符串('')。如果不是空的,FIELDS [OPTIONALLY] ENCLOSED BY 和FIELDS ESCAPED BY 值必須是一個單個字符。FIELDS TERMINATED BY 和 LINES TERMINATED BY 值可以超過一個字符。例如,為了寫入由回車換行符終止的行,或讀取包含這樣的行的文件,應該指定一個 LINES TERMINATED BY '\r\n' 子句。
舉例來說,為了讀取一個文件到一個 SQL 表中,文件以一行 %% 分隔(開玩笑的),你可以這樣做:
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 字符僅被作用于包圍 CHAR 和 VARCHAR 字段:
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 INFILE 正確讀出的輸出文件。例如,如果轉義字符為空,上面顯示的輸出將變成如下顯示的輸出。請注意第四行的第二個字段,它包含一個逗號跟在一個引號后的兩個字符,這(錯誤的)看起來像是一個字段的終止:
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 字符被解釋為單個 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 字符不是空的,它將被用于做為下列輸出字符的前綴:
FIELDS ESCAPED BY 字符
FIELDS [OPTIONALLY] ENCLOSED BY 字符
FIELDS TERMINATED BY 和 LINES TERMINATED BY 值的第一個字符。
ASCII 0 (實際上在轉義字符后寫上 ASCII '0',而不是一個零值字節)
如果 FIELDS ESCAPED BY 字符為空,沒有字符被轉義。指定一個空的轉義字符可能不是一個好的主意,特別是如果你的數據字段值中包含剛才列表中的任何字符時。
對于輸入,如果 FIELDS ESCAPED BY 字符不為空,該字符的出現將會被剝離,后續的字符在字面上做為字段值的一部分。除了一個轉義的 “0” 或 “N” (即,\0 或\N,如果轉義字符為 `\')。這些序列被解釋為 ASCII0 (一個零值字節) 和 NULL。查看下面的有關 NULL 處理的規則。
關于更多的 “\” 轉義句法信息,查看章節
在某些情況下,字段與行處理相互作用:
如果 LINES TERMINATED BY 是一個空字符串,FIELDS TERMINATED BY 是非空的,行也用 FIELDS TERMINATED BY 終止。
如果 FIELDS TERMINATED BY 和 FIELDS ENCLOSED BY 值都是空的 (''),一個固定行(無定界符) 格式被使用。用固定行格式時,在字段之間不使用分隔符。代替的,列值的寫入和讀取使用列的“顯示”寬度。例如,如果一個列被定義為 INT(7),列的值將使用 7 個字符的字段被寫入。對于輸入,列值通過讀取 7 個字符來獲得。固定行格式也影響對 NULL 值的處理;見下面。注意,如果你正在使用一個多字節的字符集,固定長度格式將不能工作。
NULL 值的處理有很多,取決于你所使用的 FIELDS 和 LINES 選項:
對于缺省的 FIELDS 和 LINES 值,輸出時,NULL 被寫成 \N,當讀入時,\N 被作為 NULL 讀入(假設ESCAPED BY 字符為 “\”)。
如果 FIELDS ENCLOSED BY 是非空的,一個字段包含文字詞 NULL 的,它的值做為一個 NULL 值被讀入 (這不同于被 FIELDS ENCLOSED BY 包圍的詞 NULL,它是被作為 'NULL' 讀入的)。
如果 FIELDS ESCAPED BY 是空的,NULL 值被寫為詞 NULL。
用固定行格式時 (它發生于 FIELDS TERMINATED BY 和 FIELDS ENCLOSED BY 兩者均為空),NULL 被寫為一個空的字符串。注意,當將表中的 NULL 值和空字符串一起寫到文件中時,它們將被混淆,因為它們都是作為空字符串被寫入的。如果你在文件時,需要對他們兩個進行區分,你不應該使用固定行格式。
一些不能被 LOAD DATA INFILE 支持的情況:
固定尺寸的記錄行 (FIELDS TERMINATED BY 和 FIELDS ENCLOSED BY 均為空) 和 BLOB 或 TEXT 列。
如果你指定一個分隔符與另一個相同,或是另一個的前綴,LOAD DATA INFILE 可能會不能正確地解釋輸入。例如,下列的 FIELDS 子句將會產生問題:FIELDS TERMINATED BY '"' ENCLOSED BY '"'
如果 FIELDS ESCAPED BY 為空,一個字段值中包含有 FIELDS ENCLOSED BY 或 LINES TERMINATED BY 被FIELDS TERMINATED BY 跟隨的值時,將會引起 LOAD DATA INFILE 過早地停止讀取一個字段或一行。這是因為 LOAD DATA INFILE 不能夠正確地決定字段或行值在哪里結果。
下面的例子將裝載 persondata 表的所有列:
mysql> LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata;
沒有字段列被指定,因而 LOAD DATA INFILE 認為輸入行包含表列中所有的字段。使用缺省的 FIELDS 和 LINES值。
如果你希望裝載表中的某些列,那指定一個字段列表:
mysql> LOAD DATA INFILE 'persondata.txt' -> INTO TABLE persondata (col1,col2,...);
如果輸入文件的字段次序不同于表中列的順序,你也必須指定一個字段列表。否則 MySQL 不知道如何將輸入字段與表中的列匹配。
如果一個行有很少的字段,沒有輸入字段的列將被設置為缺省值。缺省值賦值在章節 中被描述。
一個空的字段值不同于字段值丟失的解釋:
對于字符串類型,列被設置為空字符串。
對于數字類型,列被設置為 0。
對于日期和時間類型,列被設置為適合列類型的“零”值。查看章節 。
注意,如果在一個 INSERT 或 UPDATE 語句中明確地將一個空字符串賦給一個字符串、數字或日期或時間類型,你會得到與上面相同的結果。
如果對 TIMESTAMP 列指定一個 NULL 值,或者當字段列表被指定時, TIMESTAMP 在字段列表中被遺漏(僅僅第一個 TIMESTAMP 列被影響),TIMESTAMP 列會被設置為當前的日期和時間。
如果輸入的記錄行有太多的字段,多余的字段將被忽略,并增加警告的數目。
LOAD DATA INFILE 認為所有的輸入均是字符串,因而,對于 ENUM 或 SET 列,你不能以 INSERT 語句的形式為其設置數字值。所有的 ENUM 和 SET 必須以字符串指定!
總結
以上是生活随笔為你收集整理的LOAD DATA INFILE 语法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: excel连接mysql 数据库
- 下一篇: Excel的VBA连接数据库方法