Si vous faisiez echo($sql);
avant de l'exécuter, vous verriez que la syntaxe de votre requête est incorrecte pour les raisons suivantes :
-
Le nom de fichier doit être entouré de guillemets plutôt que de backticks car il s'agit d'une chaîne littérale et non d'un identifiant.
-
Il n'est absolument pas nécessaire d'appeler
mysql_escape_string()
pour spécifier un délimiteur dansFIELDS TERMINATED BY
etENCLOSED BY
etESCAPED BY
clauses. -
Vous abusez des backticks. En fait dans votre cas, puisqu'il n'y a pas de mots réservés utilisés, vous les abandonnez tous. Ils ne font qu'ajouter de l'encombrement.
-
À la fin de la toute première ligne de votre fichier CSV, vous devez avoir
,,,
parce que vous les utilisez dans le cadre d'un délimiteur de ligne. Si vous ne le faites pas, vous sauterez non seulement la première ligne, mais également la seconde qui contient des données. -
Vous ne pouvez pas utiliser
ENCLOSED BY
clause plus d'une fois. Vous devez composer avecNumber
champ d'une manière différente. -
En regardant vos exemples de lignes IMHO, vous n'avez pas besoin de
ESCAPED BY
. Mais si vous sentez que vous en avez besoin, utilisez-le comme ceciESCAPED BY '\\'
.
Cela étant dit, une déclaration syntaxiquement correcte pourrait ressembler à ceci
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)
Maintenant, à mon humble avis, vous devez transformer un certain nombre de champs pendant que vous les chargez :
-
si
date
dans votre table est dedatetime
type de données, il doit être transformé, sinon vous obtiendrez une erreurValeur datetime incorrecte :'18 septembre 2013 13:53:45' pour la colonne 'date' à la ligne
-
vous devez gérer des qoutes simples autour des valeurs dans
Number
champ -
vous voulez probablement changer
"null"
littéral de chaîne enNULL
réel pouraddr, pin, city, state, country
colonnes -
si la durée est toujours en secondes, vous pouvez extraire une valeur entière de secondes et la stocker de cette façon dans votre table pour pouvoir agréger facilement les valeurs de durée plus tard.
Cela étant dit, une version utile de la déclaration devrait ressembler à ceci
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')
Ci-dessous le résultat de l'exécution de la requête sur ma machine
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)
Et enfin en php assignant une chaîne de requête à $sql
la variable devrait ressembler à ceci
$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') ";