sql >> Database teknologi >  >> RDS >> Mysql

PHP - Importer CSV-fil til mysql-database ved hjælp af LOAD DATA INFILE

Hvis du ville gøre echo($sql); før du udfører det, vil du se, at syntaksen for din forespørgsel er forkert af følgende årsager:

  1. Filnavn skal være omgivet af anførselstegn i stedet for backticks, fordi det er en streng bogstavelig ikke en identifikator.

  2. Der er absolut ingen grund til at kalde mysql_escape_string() for at angive et afgrænsningstegn i FIELDS TERMINATED BY og ENCLOSED BY og ESCAPED BY klausuler.

  3. Du overbruger backticks. Faktisk i dit tilfælde, da der ikke er brugt reserverede ord, dropper du dem alle. De tilføjer kun rod.

  4. I slutningen af ​​den allerførste linje i din CSV-fil skal du have ,,, fordi du bruger dem som en del af en linjeafgrænsning. Hvis du ikke vil gøre det, springer du ikke kun den første linje over, men også den anden linje, der indeholder data.

  5. Du kan ikke bruge ENCLOSED BY klausul mere end én gang. Du skal forholde dig til Number felt på en anden måde.

  6. Når du ser på dine prøverækker IMHO, behøver du ikke ESCAPED BY . Men hvis du føler, at du har brug for det, brug det sådan her ESCAPED BY '\\' .

Når det er sagt, kan et syntaktisk korrekt udsagn se sådan ud

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 skal du IMHO transformere en hel del felter, mens du indlæser dem:

  1. hvis date i din tabel er af datetime datatype, så skal den transformeres, ellers får du en fejlmeddelelse

    Forkert datetime-værdi:'18-sep-2013 01:53:45 PM' for kolonnen 'dato' i rækken

  2. du er nødt til at håndtere enkelte citater omkring værdier i Number felt

  3. du vil højst sandsynligt ændre "null" streng bogstavelig for faktisk NULL for addr, pin, city, state, country kolonner

  4. hvis varigheden altid er i sekunder, kan du udtrække en heltalsværdi på sekunder og gemme den på den måde i din tabel for nemt at kunne aggregere varighedsværdier senere.

Når det er sagt, burde en nyttig version af erklæringen se sådan ud

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') 

Nedenfor er resultatet af at udføre forespørgslen på min maskine

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)

Og til sidst i php at tildele en forespørgselsstreng til $sql variabel skal se sådan ud

$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') ";


  1. SQLite Opret visning

  2. T-SQL:Sletter alle duplikerede rækker, men beholder én

  3. Hvad er en Bitmap-heap-scanning i en forespørgselsplan?

  4. Er det dårligt design at bruge arrays i en database?