PHP – 导入CSV文件到MySQL数据库使用LOAD DATA INFILE
我有一个.csv文件数据
Date,Name,Call Type,Number,Duration,Address,PostalCode,City,State,Country,Latitude,Longitude "Sep-18-2013 01:53:45 PM","Unknown","outgoing call",'123456',"0 Secs","null","null","null","null","null",0.0,0.0,,, "Sep-18-2013 01:54:14 PM","Unknown","outgoing call",'1234567890',"0 Secs","null","null","null","null","null",0.0,0.0,,, "Sep-18-2013 01:54:37 PM","Unknown","outgoing call",'14772580369',"1 Secs","null","null","null","null","null",0.0,0.0,,,
并使用下面的代码将数据插入到数据库中
$sql = "LOAD DATA INFILE `detection.csv` INTO TABLE `calldetections` FIELDS TERMINATED BY '".@mysql_escape_string(","). "` OPTIONALLY ENCLOSED BY `".@mysql_escape_string("\""). "` OPTIONALLY ENCLOSED BY `".@mysql_escape_string("\'"). "` ESCAPED BY `".@mysql_escape_string("\\"). "` LINES TERMINATED BY `".",,,\\r\\n". "`IGNORE 1 LINES `" ."(`date`,`name`,`type`,`number`,`duration`,`addr`,`pin`,`city`,`state`,`country`,`lat`,`log`)"; $res = @mysql_query($con,$sql);
但没有插入任何东西; 错误在哪里?
如果你会做echo($sql);
在执行之前,你会发现你的查询语法不正确,原因如下:
-
文件名应该用引号引起来,而不是反引号,因为它是一个string,而不是一个标识符。
-
绝对不需要调用
mysql_escape_string()
在FIELDS TERMINATED BY
和ENCLOSED BY
和ESCAPED BY
子句中指定分隔符。 -
你过分使用反斜杠 事实上,就你而言,由于没有使用保留字,所以你把它们都抛弃了。 他们只会增加混乱。
-
在CSV文件的第一行结尾处,您必须具有
,,,
因为您将它们用作行分隔符的一部分。 如果你不这样做,你不仅会跳过第一行,而且会跳过包含数据的第二行。 -
您不能多次使用
ENCLOSED BY
子句。 你必须以不同的方式处理Number
字段。 -
望着你的示例行恕我直言,你不需要
ESCAPED BY
。 但是,如果你觉得你需要它像这样ESCAPED BY '\\'
。
这是一个句法正确的陈述可能看起来像这样
LOAD DATA INFILE 'detection.csv' INTO TABLE calldetections FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY ',,,\r\n' IGNORE 1 LINES (date, name, type, number, duration, addr, pin, city, state, country, lat, log)
现在恕我直言,你需要转换相当多的领域,而你加载它们:
-
如果你的表中的
datetime
是datetime
数据types,那么它需要被转换,否则你会得到一个错误不正确的date时间值:'Sep-18-2013 01:53:45 PM'列'date'在行
-
你必须在
Number
域中处理单个qoutes值 -
你很可能希望将
"null"
string文字更改为addr, pin, city, state, country
列的实际NULL
-
如果持续时间总是以秒为单位,那么您可以提取一个秒的整数值并将其以这种方式存储在您的表中,以便稍后可以轻松地汇总持续时间值。
这就是说声明的有用版本应该看起来像这样
LOAD DATA INFILE 'detection.csv' INTO TABLE calldetections FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY ',,,\r\n' IGNORE 1 LINES (@date, name, type, @number, @duration, @addr, @pin, @city, @state, @country, lat, log) SET date = STR_TO_DATE(@date, '%b-%d-%Y %h:%i:%s %p'), number = TRIM(BOTH '\'' FROM @number), duration = 1 * TRIM(TRAILING 'Secs' FROM @duration), addr = NULLIF(@addr, 'null'), pin = NULLIF(@pin, 'null'), city = NULLIF(@city, 'null'), state = NULLIF(@state, 'null'), country = NULLIF(@country, 'null')
以下是在我的机器上执行查询的结果
mysql> LOAD DATA INFILE'/tmp/detection.csv' - > INTO TABLE calldetections - > FIELDS TERMINATED BY',' - >任选地由''' - > LINES TERMINATED BY',,, \ n' - > IGNORE 1 LINES - >(@date,name,type,@number,@duration,@addr,@pin,@city,@state,@country,lat,log) - > SET date = STR_TO_DATE(@date,'%b-%d-%Y%h:%i:%s%p') - > number = TRIM(BOTH'\'from @number), - > duration = 1 * TRIM(TRAILING'Secs'FROM @duration), - > addr = NULLIF(@addr,'null'), - > pin = NULLIF(@pin,'null'), - > city = NULLIF(@city,'null'), - > state = NULLIF(@state,'null'), - > country = NULLIF(@country,'null'); 查询OK,3行受影响(0.00秒) logging:3删除:0跳过:0警告:0 mysql> select * from calldetections; + --------------------- + --------- + --------------- + - ------------ + ---------- + ------ + ------ + ------ + ----- - + --------- + ------ + ------ + | date| 名字| 键入| 数字| 持续时间| addr | pin | 城市| 状态| 国家| lat | log | + --------------------- + --------- + --------------- + - ------------ + ---------- + ------ + ------ + ------ + ----- - + --------- + ------ + ------ + | 2013-09-18 13:53:45 | 未知| 传出呼叫| 123456 | 0 | NULL | NULL | NULL | NULL | NULL | 0.0 | 0.0 | | 2013-09-18 13:54:14 | 未知| 传出呼叫| 1234567890 | 0 | NULL | NULL | NULL | NULL | NULL | 0.0 | 0.0 | | 2013-09-18 13:54:37 | 未知| 传出呼叫| 14772580369 | 1 | NULL | NULL | NULL | NULL | NULL | 0.0 | 0.0 | + --------------------- + --------- + --------------- + - ------------ + ---------- + ------ + ------ + ------ + ----- - + --------- + ------ + ------ + 3行(0.00秒)
最后在PHP分配一个查询string$sql
variables应该看起来像这样
$sql = "LOAD DATA INFILE 'detection.csv' INTO TABLE calldetections FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY ',,,\\r\\n' IGNORE 1 LINES (@date, name, type, @number, @duration, @addr, @pin, @city, @state, @country, lat, log) SET date = STR_TO_DATE(@date, '%b-%d-%Y %h:%i:%s %p'), number = TRIM(BOTH '\'' FROM @number), duration = 1 * TRIM(TRAILING 'Secs' FROM @duration), addr = NULLIF(@addr, 'null'), pin = NULLIF(@pin, 'null'), city = NULLIF(@city, 'null'), state = NULLIF(@state, 'null'), country = NULLIF(@country, 'null') ";
在1分钟内在数据库中插入大于7000000条logging(超快查询与计算)
mysqli_query($cons, ' LOAD DATA LOCAL INFILE "'.$file.'" INTO TABLE tablename FIELDS TERMINATED by \',\' LINES TERMINATED BY \'\n\' IGNORE 1 LINES (isbn10,isbn13,price,discount,free_stock,report,report_date) SET RRP = IF(discount = 0.00,price-price * 45/100,IF(discount = 0.01,price,IF(discount != 0.00,price-price * discount/100,@RRP))), RRP_nl = RRP * 1.44 + 8, RRP_bl = RRP * 1.44 + 8, ID = NULL ')or die(mysqli_error()); $affected = (int) (mysqli_affected_rows($cons))-1; $log->lwrite('Inventory.CSV to database:'. $affected.' record inserted successfully.');
RRP和RRP_nl和RRP_bl不在csv中,但是我们计算出来并插入之后。