Mysql
 sql >> база данни >  >> RDS >> Mysql

PHP - Импортиране на CSV файл в mysql база данни с помощта на LOAD DATA INFILE

Ако бихте направили echo($sql); преди да го изпълните, ще видите, че синтаксисът на вашата заявка е неправилен поради следните причини:

  1. Името на файла трябва да бъде затворено в кавички, а не в обратни отметки, защото това е низов литерал, а не идентификатор.

  2. Няма абсолютно никаква нужда да извикате mysql_escape_string() за да посочите разделител в FIELDS TERMINATED BY и ENCLOSED BY и ESCAPED BY клаузи.

  3. Прекалявате с тиковете. Всъщност във вашия случай, тъй като няма използвани запазени думи, вие ги изхвърляте всички. Те само добавят безпорядък.

  4. В края на първия ред на вашия CSV файл, който трябва да имате ,,, защото ги използвате като част от разделител на ред. Ако не го направите, ще пропуснете не само първия ред, но и втория, който съдържа данни.

  5. Не можете да използвате ENCLOSED BY клауза повече от веднъж. Трябва да се справите с Number поле по различен начин.

  6. Гледайки примерните си редове 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 трябва да трансформирате доста полета, докато ги зареждате:

  1. ако date във вашата таблица е с datetime тип данни, тогава той трябва да бъде трансформиран, в противен случай ще получите грешка

    Неправилна стойност за дата и час:„Sep-18-2013 01:53:45 PM“ за колона „date“ на ред

  2. трябва да се справите с единични кавички около стойности в Number поле

  3. най-вероятно искате да промените "null" низов литерал до действителен NULL за addr, pin, city, state, country колони

  4. ако продължителността винаги е в секунди, тогава можете да извлечете целочислена стойност от секунди и да я съхраните по този начин във вашата таблица, за да можете лесно да обобщите стойностите за продължителност по-късно.

Като се има предвид това, полезна версия на изявлението трябва да изглежда така

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да създадете GraphQL API без сървър за MySQL, Postgres и Aurora

  2. Скриване на истинския идентификатор на обект на база данни в url

  3. Как да направя групово вмъкване в mySQL с помощта на node.js

  4. Neo4j - Изтриване на връзка с помощта на Cypher

  5. Как да изчислим пълзящата средна в MySQL