1. 程式人生 > >MySQL 匯入匯出 CSV 檔案

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)

解決方案有兩個:

  1. 將檔案複製到 secure_file_priv 指定的安全目錄。推薦。
  2. /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 頭:
Notepad++

部分資料儲存失敗,且有異常資料

資料中出現了雙引號,且部分資料插入失敗,並插入了部分異常資料:
error
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