chi*_*mbu 14 php mysql sql csv 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,,,
Run Code Online (Sandbox Code Playgroud)
我正在使用以下代码将数据插入数据库
$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);
Run Code Online (Sandbox Code Playgroud)
但没有插入; 哪里出错了?
pet*_*erm 41
如果您在执行echo($sql);
之前执行此操作,则会发现查询的语法不正确,原因如下:
文件名应该用引号括起来,而不是反引号,因为它是字符串文字而不是标识符.
绝对不需要调用mysql_escape_string()
在FIELDS TERMINATED BY
and 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)
Run Code Online (Sandbox Code Playgroud)
现在恕我直言,你需要在加载它们时转换相当多的字段:
如果date
你的表中有datetime
数据类型,则需要进行转换,否则会出错
日期时间值不正确:'Sep-18-2013 01:53:45 PM'列的'date'列
你必须处理Number
字段中值的单个qoutes
你最有可能要更改"null"
字符串字面量实际NULL
为addr, pin, city, state, country
列
如果持续时间总是以秒为单位,那么您可以提取秒的整数值并将其存储在表中,以便以后轻松汇总持续时间值.
据说这个语句的有用版本看起来应该是这样的
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')
Run Code Online (Sandbox Code Playgroud)
以下是在我的机器上执行查询的结果
mysql> LOAD DATA INFILE '/tmp/detection.csv' -> INTO TABLE calldetections -> FIELDS TERMINATED BY ',' -> OPTIONALLY ENCLOSED 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'); Query OK, 3 rows affected (0.00 sec) Records: 3 Deleted: 0 Skipped: 0 Warnings: 0 mysql> select * from calldetections; +---------------------+---------+---------------+-------------+----------+------+------+------+-------+---------+------+------+ | date | name | type | number | duration | addr | pin | city | state | country | lat | log | +---------------------+---------+---------------+-------------+----------+------+------+------+-------+---------+------+------+ | 2013-09-18 13:53:45 | Unknown | outgoing call | 123456 | 0 | NULL | NULL | NULL | NULL | NULL | 0.0 | 0.0 | | 2013-09-18 13:54:14 | Unknown | outgoing call | 1234567890 | 0 | NULL | NULL | NULL | NULL | NULL | 0.0 | 0.0 | | 2013-09-18 13:54:37 | Unknown | outgoing call | 14772580369 | 1 | NULL | NULL | NULL | NULL | NULL | 0.0 | 0.0 | +---------------------+---------+---------------+-------------+----------+------+------+------+-------+---------+------+------+ 3 rows in set (0.00 sec)
最后在php中为$sql
变量分配查询字符串应该如下所示
$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') ";
Run Code Online (Sandbox Code Playgroud)