Als je echo($sql);
. zou doen voordat u het uitvoert, ziet u dat de syntaxis van uw zoekopdracht om de volgende redenen onjuist is:
-
Bestandsnaam moet tussen aanhalingstekens staan in plaats van backticks, omdat het een letterlijke tekenreeks is en geen identifier.
-
Het is absoluut niet nodig om
mysql_escape_string()
. aan te roepen om een scheidingsteken op te geven inFIELDS TERMINATED BY
enENCLOSED BY
enESCAPED BY
clausules. -
Je gebruikt te veel backticks. In jouw geval, aangezien er geen gereserveerde woorden worden gebruikt, gooi je ze allemaal weg. Ze voegen alleen maar rommel toe.
-
Aan het einde van de allereerste regel van je CSV-bestand moet je moeten
,,,
omdat je ze gebruikt als onderdeel van een lijnscheidingsteken. Als je dat niet doet, sla je niet alleen de eerste regel over, maar ook de tweede regel die gegevens bevat. -
Je kunt
ENCLOSED BY
niet gebruiken clausule meer dan eens. Je hebt te maken metNumber
veld op een andere manier. -
Als je naar je voorbeeldrijen kijkt, heb je IMHO
ESCAPED BY
niet nodig . Maar als je denkt dat je het nodig hebt, gebruik het dan als volgtESCAPED BY '\\'
.
Dat gezegd hebbende, zou een syntactisch correcte uitspraak er zo uit kunnen zien
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)
Nu moet je IMHO nogal wat velden transformeren terwijl je ze laadt:
-
als
date
in je tabel is vandatetime
gegevenstype dan moet het worden getransformeerd, anders krijg je een foutmeldingOnjuiste datetime-waarde:'Sep-18-2013 01:53:45 PM' voor kolom 'date' op rij
-
je hebt te maken met enkele qoutes rond waarden in
Number
veld -
u wilt hoogstwaarschijnlijk
"null"
. wijzigen tekenreeks letterlijk naar feitelijkNULL
vooraddr, pin, city, state, country
kolommen -
als de duur altijd in seconden is, kun je een geheel getal van seconden extraheren en op die manier in je tabel opslaan om later gemakkelijk de duurwaarden te kunnen aggregeren.
Dat gezegd hebbende, zou een bruikbare versie van de verklaring er ongeveer zo uit moeten zien
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')
Hieronder staat het resultaat van het uitvoeren van de query op mijn computer
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)
En tot slot in php een queryreeks toewijzen aan $sql
variabele zou er zo uit moeten zien
$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') ";