如果您在执行之前执行echo($sql);,您会发现查询的语法不正确,原因如下:
文件名应该用引号而不是反引号括起来,因为它是字符串文字而不是标识符。
绝对没有必要在FIELDS TERMINATED BY、ENCLOSED BY和ESCAPED BY子句中调用mysql_escape_string()来指定分隔符。
你过度使用反引号。实际上,在您的情况下,由于没有使用保留字,因此您将它们全部丢弃。它们只会增加混乱。
在 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)
现在恕我直言,您需要在加载时转换相当多的字段:
-
如果你表中的date是datetime数据类型,那么它需要被转换,否则你会得到一个错误
日期时间值不正确:行中“日期”列的“日期”列“2013 年 9 月 18 日 01:53:45”
您必须处理围绕 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')
下面是在我的机器上执行查询的结果
mysql> 加载数据输入文件'/tmp/detection.csv'
-> INTO TABLE 调用检测
-> 由“,”终止的字段
-> 可选地由 '"' 包围
-> 以 ',,,\n' 结尾的行
-> 忽略 1 行
->(@日期、名称、类型、@number、@duration、@addr、@pin、@city、@state、@country、lat、log)
-> 设置日期 = STR_TO_DATE(@date, '%b-%d-%Y %h:%i:%s %p'),
-> number = TRIM(BOTH '\'' FROM @number),
-> 持续时间 = 1 * TRIM(TRAILING 'Secs' FROM @duration),
-> addr = NULLIF(@addr, 'null'),
-> pin = NULLIF(@pin, 'null'),
-> 城市 = NULLIF(@city, 'null'),
-> 状态 = NULLIF(@state, 'null'),
-> 国家 = NULLIF(@country, 'null');
查询正常,3 行受影响(0.00 秒)
记录:3 删除:0 跳过:0 警告:0
mysql> select * from calldetections;
+----------+---------+--------------+- ------------+----------+------+------+------+----- --+---------+------+------+
|日期 |姓名 |类型 |号码 |持续时间 |地址 |销 |城市|状态 |国家 |纬度 |日志 |
+----------+---------+--------------+- ------------+----------+------+------+------+----- --+---------+------+------+
| 2013-09-18 13:53:45 |未知 |拨出电话 | 123456 | 0 |空 |空 |空 |空 |空 | 0.0 | 0.0 |
| 2013-09-18 13:54:14 |未知 |拨出电话 | 1234567890 | 0 |空 |空 |空 |空 |空 | 0.0 | 0.0 |
| 2013-09-18 13:54:37 |未知 |拨出电话 | 14772580369 | 1 |空 |空 |空 |空 |空 | 0.0 | 0.0 |
+----------+---------+--------------+- ------------+----------+------+------+------+----- --+---------+------+------+
3 行一组(0.00 秒)
最后在 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') ";