Ако бихте направили echo($sql);
преди да го изпълните, ще видите, че синтаксисът на вашата заявка е неправилен поради следните причини:
-
Името на файла трябва да бъде затворено в кавички, а не в обратни отметки, защото това е низов литерал, а не идентификатор.
-
Няма абсолютно никаква нужда да извикате
mysql_escape_string()
за да посочите разделител вFIELDS TERMINATED BY
иENCLOSED BY
иESCAPED BY
клаузи. -
Прекалявате с тиковете. Всъщност във вашия случай, тъй като няма използвани запазени думи, вие ги изхвърляте всички. Те само добавят безпорядък.
-
В края на първия ред на вашия CSV файл, който трябва да имате
,,,
защото ги използвате като част от разделител на ред. Ако не го направите, ще пропуснете не само първия ред, но и втория, който съдържа данни. -
Не можете да използвате
ENCLOSED BY
клауза повече от веднъж. Трябва да се справите сNumber
поле по различен начин. -
Гледайки примерните си редове IMHO, нямате нужда от
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)
Сега IMHO трябва да трансформирате доста полета, докато ги зареждате:
-
ако
date
във вашата таблица е сdatetime
тип данни, тогава той трябва да бъде трансформиран, в противен случай ще получите грешкаНеправилна стойност за дата и час:„Sep-18-2013 01:53:45 PM“ за колона „date“ на ред
-
трябва да се справите с единични кавички около стойности в
Number
поле -
най-вероятно искате да промените
"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> 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') ";