CSV数据未插入相应的MySQL表中

时间:2013-10-15 21:04:51

标签: mysql csv mysqlimport

我有一个遵循这种模式的CSV文件:

cust_id,cust_name,cust_add_1,cust_add_2,cust_city,cust_state,cust_zip,cust_email
100024,BALE #DIANA & ROY,2944 SOME RD, ,AKRON,OH,44556,an@other.net
100139,SMITH #JOHN & LINDA,1569 ANOTHER WAY, ,SARASOTA,FL,65478,
100263,DOLE #BOB,5947 LONG RD, ,GRANITE FALLS,NC,12345,
.
.
. continued

此文件代表成千上万行数据,我试图将所有数据插入到MySQL表中。我使用以下语句创建了相应的表:

CREATE TABLE customer (
    cust_id INT(7) NOT NULL,
    cust_name VARCHAR(40) NOT NULL,
    cust_add_1 VARCHAR(50) NOT NULL,
    cust_add_2 VARCHAR(50),
    cust_city VARCHAR(20) NOT NULL,
    cust_state CHAR(2) NOT NULL,
    cust_zip INT(5) NOT NULL,
    cust_email VARCHAR(60),
    PRIMARY KEY (cust_id)
);

然后我在命令行上尝试了以下操作:

msyqlimport -u root --local csv_import ~/path/to/customer.csv

当我在运行mysqlimport后尝试SELECT * FROM customer时,我得到了以下结果集:

+---------+-----------+------------+------------+-----------+------------+----------+------------+
| cust_id | cust_name | cust_add_1 | cust_add_2 | cust_city | cust_state | cust_zip | cust_email |
+---------+-----------+------------+------------+-----------+------------+----------+------------+
|       0 |           |            | NULL       |           |            |          | NULL       |
+---------+-----------+------------+------------+-----------+------------+----------+------------+
1 row in set (0.00 sec)

我在将CSV数据导入MySQL方面不是很有经验,非常感谢任何帮助。

更新

根据ThisSuitIsBlackNot的回答,我尝试了以下命令(BTW需要--local选项):

mysqlimport -u root --local --fields-terminated-by=',' --fields-optionally-enclosed-by='"' --lines-terminated-by='\n' csv_import ~/path/to/customer.csv

这产生了稍微好一点的结果,但不是我需要的,所以我尝试了这样:

mysql> LOAD DATA LOCAL INFILE '~/path/to/customer.csv'
    -> INTO TABLE customer
    -> FIELDS TERMINATED BY ','
    -> OPTIONALLY ENCLOSED BY '"'
    -> LINES TERMINATED BY '\n';

在这两个之后,SELECT * FROM customer产生了这个结果集:

+---------+-----------+------------+------------+-----------+------------+----------+-------------------+
| cust_id | cust_name | cust_add_1 | cust_add_2 | cust_city | cust_state | cust_zip | cust_email        |
+---------+-----------+------------+------------+-----------+------------+----------+-------------------+
100024 |0 | cust_name | cust_add_1 | cust_add_2 | cust_city | cu         | cust_    | cust_email
+---------+-----------+------------+------------+-----------+------------+----------+-------------------+
1 row in set (0.00 sec)

这显然不是我需要的,但它越来越近了。

1 个答案:

答案 0 :(得分:2)

字段分隔符

mysqlimport的默认字段分隔符是制表符。您需要告诉mysqlimport在逗号上拆分字段:

mysqlimport --fields-terminated-by=',' ...

这还不够,因为如果您的CSV遵循规范,则包含逗号的字段将被双引号括起来。您需要告诉mysqlimport它不应该将引号内的逗号视为字段分隔符:

mysqlimport --fields-terminated-by=',' --fields-optionally-enclosed-by='"' ...

在某些CSV中,所有字段都是双引号,无论它们是否包含逗号。您的数据不是这种情况,但为了将来参考,mysqlimport还提供了选项

--fields-enclosed-by=string

我不确定,但我认为如果您使用--fields-enclosed-by='"'代替--fields-optionally-enclosed-by='"',则引用所有字段的CSV会有更好的表现。

行分隔符

mysqlimport的默认行分隔符是换行符\n。这适用于在UNIX / Linux / Mac OS X上生成的文件,但如果文件中的EOL序列不同(例如,在Windows上创建的大多数文件中为\r\n),则还需要指定:

mysqlimport --lines-terminated-by='\r\n'

显然,Wordpad使用'\ r'作为行尾,Mac OS X之前的Mac也是如此。

跳过列标题

通常,您不希望将列的名称导入表中,因为该表已有自己的列名。您可以跳过文件中的前X行数:

mysqlimport --ignore-lines=X

全部放在一起

导入CSV文件

  • 包含逗号的字段是双引号
  • 不引用逗号的字段
  • 行以\r\n
  • 结尾
  • 第一行包含要忽略的列名称

你会跑

mysqlimport --fields-terminated-by=',' \
            --fields-optionally-enclosed-by='"' \
            --lines-terminated-by='\r\n' \
            --ignore-lines=1 \
            db_name table_name.csv

请注意,mysqlimport通过简单地剥离文件扩展名来确定要导入的表,因此上面的示例将尝试将数据从table_name.csv导入table_name表。此外,如果您在服务器上运行此操作,则不应该需要--local选项,尽管文档中的措辞有点迟钝。

您还可以使用等效的SQL语句

LOAD DATA INFILE 'table_name.csv' INTO TABLE table_name
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\r\n'
  IGNORE 1 LINES;

mysqlimport只是LOAD DATA INFILE)的命令行界面

有关详细信息,请参阅LOAD DATA INFILE {{1}}。