MySQL 匯入匯出 CSV 檔案
匯入
示例:
LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table;
LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n';
常用引數:
FIELDS TERMINATED BY ','
:指定欄位分隔符OPTIONALLY ENCLOSED BY '"'
:認為雙引號中的是一個獨立的欄位。Excel 轉 CSV 時,有特殊字元(逗號、頓號等)的欄位,會自動用雙引號引起來LINES TERMINATED BY '\n'
:指定行分隔符,注意,在 Windows 平臺上建立的檔案,分隔符是'\r\n'
匯出
SELECT … INTO 語法可以將查詢結果儲存到變數或檔案中:
SELECT ... INTO var_list # 將欄位的值儲存到變數中
SELECT ... INTO OUTFILE # 將選中的行儲存到檔案中。可以指定列和行的結束符,以生成指定格式的檔案。
SELECT ... INTO DUMPFILE # 將一個單獨的行寫入檔案中,沒有格式
示例:
mysql > SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM test_table;
mysql> SELECT * INTO OUTFILE '/var/lib/mysql-files/1.txt'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM professions;
Query OK, 2220 rows affected (0.04 sec)
常用引數(跟 LOAD DATA INFILE
語法一樣):
FIELDS TERMINATED BY ','
:指定欄位分隔符OPTIONALLY ENCLOSED BY '"'
:認為雙引號中的是一個獨立的欄位。Excel 轉 CSV 時,有特殊字元(逗號、頓號等)的欄位,會自動用雙引號引起來LINES TERMINATED BY '\n'
:指定行分隔符,注意,在 Windows 平臺上建立的檔案,分隔符是'\r\n'
清空表中的所有資料
操作失誤時,需要簡單的方式清空表,有兩種方式:不帶 where 引數的 delete 語句,或 truncate。
delete from my_table;
truncate table my_table;
truncate 相當於使用表的結構重新建立表,所有的狀態都相當於新表。
不帶 where 引數的 delete 則是將表中所有記錄一條一條刪除。
truncate 比 delete 快,但 truncate 刪除後不記錄日誌,資料無法恢復。
注意事項
Windows 中用 Excel 匯出的 CSV 檔案,採用 UTF-8-BOM 編碼,換行符是 CRLF 回車換行。但是在 Linux 中不支援 UTF-8-BOM 編碼,需要手動轉為 UTF-8 編碼。如果換行符用 CRLF 回車換行,則需要在 LOAD DATA INFILE
命令中通過 LINES TERMINATED BY '\r\n'
明確指定換行符:
LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n';
如果已經轉為 LF 換行了,則可以省略這一句。
常見問題
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
這一般是因為,你上傳或下載的檔案沒有在 MySQL 指定的安全目錄中。預設情況下,MySQL 匯入匯出檔案時,只能使用安全目錄。使用下面的命令檢視 MySQL 的安全目錄:
mysql> SHOW VARIABLES LIKE "secure_file_priv";
+--------------------------+-----------------------+
| Variable_name | Value |
+--------------------------+-----------------------+
| require_secure_transport | OFF |
| secure_auth | ON |
| secure_file_priv | /var/lib/mysql-files/ |
+--------------------------+-----------------------+
3 rows in set (0.00 sec)
解決方案有兩個:
- 將檔案複製到
secure_file_priv
指定的安全目錄。推薦。 - 在
/etc/my.cnf
配置檔案(Windows 平臺下是my.ini
)中關閉secure_file_priv
。這個選項無法動態配置,修改後必須重啟。
對於第一個方案,複製檔案到安全目錄後,需要使用完整路徑:
mysql> load data infile '/var/lib/mysql-files/profession.csv' into table professionss fields terminated by ',' lines terminated by '\n';
資料中的第一個欄位始終報錯
如果是整數,則報錯如下:
ERROR 1366 (HY000): Incorrect integer value: '1800' for column 'CompanyID' at row 1
Windows 平臺下建立的檔案基本上都使用了 BOM 頭,即在檔案的頭部新增描述性資訊,可以參考 這裡。這會在 Linux 平臺下導致致命錯誤,去掉這個 BOM 頭就好了。
Excel 另存為 CSV 檔案後,預設編碼是“使用 UTF-8 BOM 編碼”,在 Notepad++ 中開啟檔案,選擇“使用 UTF-8 編碼”儲存即可清除 BOM 頭:
部分資料儲存失敗,且有異常資料
資料中出現了雙引號,且部分資料插入失敗,並插入了部分異常資料:
Excel 另存為 CSV 檔案後,對於特殊字元(逗號、頓號等)的欄位,會自動用雙引號引起來。但是新增的雙引號的位置竟然會出錯:
1800,1,3,2021304,202,"計算機系統分析技術人員
",1
1800,1,3,2021305,202,"維護工程師
",2
1800,1,3,2021306,202,"銷售工程師
",1
可以看到,好多行發生了不應該的換行。兩個解決方案:
- 使用
OPTIONALLY ENCLOSED BY '"'
自動處理,推薦:
mysql> LOAD DATA INFILE '/var/lib/mysql-files/profession.csv' INTO TABLE professionss FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n';
Query OK, 2220 rows affected (0.06 sec)
Records: 2220 Deleted: 0 Skipped: 0 Warnings: 0
- 通過正則批量替換將
\n",
替換為,
使表格資料沒有問題:
mysql> LOAD DATA INFILE '/var/lib/mysql-files/profession.csv' INTO TABLE professionss FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
Query OK, 2220 rows affected (0.06 sec)
Records: 2220 Deleted: 0 Skipped: 0 Warnings: 0