在LOAD INFILE到MySQL之前转义CSV文件

时间:2012-12-17 20:19:59

标签: php mysql phpmyadmin

我正在编写一个脚本,该脚本会定期将CSV文件上传到MySQL数据库中。问题是CSV文件中的一个字段包含用户生成的文本,其中可能包含引号和对MySQL不友好的其他字符。

我已经确定上传CSV文件的最有效方法是通过MySQL' LOAD DATA INFILE'命令。以下是我上传CSV时在MyPHPAdmin中显示的命令:

LOAD DATA LOCAL INFILE '/home/myfolder/tmp/property_re_1.csv' REPLACE INTO TABLE `markers`
    FIELDS TERMINATED BY ';' ENCLOSED BY '"' ESCAPED BY '\\'
    LINES TERMINATED BY '\r\n' # 2 rows affected.

简单地使用此命令加载CSV不起作用,因为该过程一旦遇到'''' " ESCAPED BY' \'"似乎没有达到其目的。

在这种情况下,我想我可能必须先用PHP以编程方式转义CSV文件中的引号。然后加载" Escaped"使用SQL中的LOAD DATA INFILE命令将文件存入MySQL。

我确信这是一个常见的问题,有一个"最佳实践"解。从本质上讲,我的脚本需要清理"将CSV文件加载到MYSQL表之前的文件。

以下是我正在使用的实际SQL表格和CSV文件的链接,以帮助更聪明的人围绕这一点:https://www.dropbox.com/sh/4iq10i51qlqyq8q/UjEQwvXKDA

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

保管框上的数据文件包含由,分隔的字段,可选地由"括起,由\n分隔并包含标题行的行;而您上面的陈述是针对包含;分隔的字段的文件,始终由"括起,由\r\n分隔且不包含任何标题行的行。

也就是说,它也适用于名为data.csv的文件,而Dropbox上的文件名为property_re_1.csv

mysql> CREATE TABLE IF NOT EXISTS `markers` (
    ->   `L_ListingID` int(20) NOT NULL,
    ->   `L_Class` int(5) NOT NULL,
    ->   `L_Type_` int(10) NOT NULL,
    ->   `L_Status` varchar(10) NOT NULL,
    ->   `L_AskingPrice` float NOT NULL,
    ->   `L_Remarks` text NOT NULL,
    ->   `L_Address` varchar(50) NOT NULL,
    ->   `L_City` text NOT NULL,
    ->   `L_State` varchar(10) NOT NULL,
    ->   `LO1_OrganizationName` varchar(65) NOT NULL,
    ->   `LA1_AgentLicenseID` int(20) NOT NULL,
    ->   `LA1_UserFirstName` varchar(50) NOT NULL,
    ->   `LA1_UserLastName` varchar(50) NOT NULL,
    ->   `L_PictureCount` int(4) NOT NULL,
    ->   PRIMARY KEY (`L_ListingID`)
    -> ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Query OK, 0 rows affected (0.21 sec)

mysql> LOAD DATA LOCAL INFILE 'property_re_1.csv' 
    -> REPLACE INTO TABLE `markers`
    -> FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\'
    -> LINES TERMINATED BY '\n' IGNORE 1 LINES;
Query OK, 315 rows affected (0.01 sec)
Records: 315  Deleted: 0  Skipped: 0  Warnings: 0