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. フラッシュキャッシュのピンテーブル