sql >> Databáze >  >> RDS >> Mysql

PHP - Import CSV souboru do mysql databáze pomocí LOAD DATA INFILE

Pokud byste udělali echo($sql); než jej spustíte, uvidíte, že syntaxe vašeho dotazu je nesprávná z následujících důvodů:

  1. Název souboru by měl být uzavřen v uvozovkách, nikoli zpětným zaškrtnutím, protože se jedná o řetězcový doslov, nikoli identifikátor.

  2. Není absolutně nutné volat mysql_escape_string() k určení oddělovače v FIELDS TERMINATED BY a ENCLOSED BY a ESCAPED BY klauzule.

  3. Nadměrně využíváte zpětné tahy. Ve skutečnosti ve vašem případě, protože nejsou použita žádná vyhrazená slova, je všechny zavrhnete. Přidávají jen nepořádek.

  4. Na konci úplně prvního řádku vašeho souboru CSV, který musíte mít ,,, protože je používáte jako součást oddělovače řádků. Pokud to neuděláte, přeskočíte nejen první řádek, ale i druhý řádek, který obsahuje data.

  5. Nemůžete použít ENCLOSED BY doložka více než jednou. Musíte se vypořádat s Number pole jiným způsobem.

  6. Když se podíváte na ukázkové řádky, IMHO nepotřebujete ESCAPED BY . Ale pokud máte pocit, že to potřebujete, použijte to takto ESCAPED BY '\\' .

Jak bylo řečeno, syntakticky správný příkaz může vypadat takto

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)

Nyní IMHO potřebujete transformovat několik polí, zatímco je načítáte:

  1. pokud date ve vaší tabulce je datetime datový typ, pak je třeba jej transformovat, jinak se zobrazí chyba

    Nesprávná hodnota data a času:'Sep-18-2013 01:53:45 PM' pro sloupec 'date' na řádku

  2. musíte se vypořádat s jednotlivými qoutes kolem hodnot v Number pole

  3. pravděpodobně budete chtít změnit "null" řetězec doslovný ke skutečnému NULL pro addr, pin, city, state, country sloupce

  4. pokud je trvání vždy v sekundách, můžete extrahovat celočíselnou hodnotu v sekundách a uložit ji tímto způsobem do tabulky, abyste mohli později snadno agregovat hodnoty trvání.

Užitečná verze prohlášení by měla vypadat nějak takto

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

Níže je uveden výsledek provádění dotazu na mém počítači

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)

A nakonec v php přiřazení řetězce dotazu k $sql proměnná by měla vypadat takto

$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. Jak používat JDBC k připojení databáze MySql

  2. Hodnota sloupce identity náhle vyskočí na 1001 na serveru SQL

  3. MySQL:Jak povolit vzdálené připojení k mysql

  4. Neznámý sloupec MySQL v klauzuli ON