sql >> データベース >  >> RDS >> Mysql

PHP-LOADDATAINFILEを使用してCSVファイルをmysqlデータベースにインポートします

    echo($ sql);を実行する場合 実行する前に、次の理由でクエリの構文が正しくないことがわかります。

    1. ファイル名は識別子ではなく文字列リテラルであるため、バッククォートではなく引用符で囲む必要があります。

    2. mysql_escape_string()を呼び出す必要はまったくありません。 FIELDS TERMINATED BYで区切り文字を指定します およびENCLOSEDBY およびESCAPEDBY 条項。

    3. バックティックを使いすぎます。実際、あなたの場合、予約語は使用されていないので、それらをすべて捨てます。散らかるだけです。

    4. CSVファイルの最初の行の最後に必要があります 、、、 行区切り文字の一部として使用するためです。そうしない場合は、最初の行だけでなく、データを含む2番目の行もスキップします。

    5. ENCLOSED BYは使用できません 条項が複数回あります。 Numberを処理する必要があります 別の方法でフィールド。

    6. サンプル行を見ると、 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)
    

    今、私見では、ロード中にかなりの数のフィールドを変換する必要があります:

    1. dateの場合 テーブル内のdatetime データ型の場合は変換する必要があります。変換しないとエラーが発生します

      日付時刻の値が正しくありません:'Sep-18-2013 01:53:45 PM' for column'date' at row

    2. Numberの値の周りの単一のqoutesを処理する必要があります フィールド

    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. MySQLでの行カウントの高速化

    2. メッセージ8672、レベル16、状態1、行1 MERGEステートメントが、同じ行を複数回更新または削除しようとしました

    3. SQL Serverで、特定のテーブルに対してCREATE TABLEステートメントを生成するにはどうすればよいですか?

    4. フラッシュキャッシュのピンテーブル