16

MySQLには優れたCSVインポート機能がありますLOAD DATA INFILE

定期的にCSVからインポートする必要がある大きなデータセットがあるので、この機能はまさに私が必要としているものです。データを完全にインポートする動作するスクリプトがあります。

.....例外....行末ターミネータがどうなるかは事前にわかりません。

私のSQLコードは現在次のようになっています。

LOAD DATA INFILE '{fileName}'
 INTO TABLE {importTable}
 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
 LINES TERMINATED BY '\n'
 IGNORE 1 LINES
( {fieldList} );

これは、一部のインポートファイルに最適です。

ただし、インポートデータは複数のソースから取得されています。それらのいくつかには\nターミネーターがあります。他の人が持ってい\r\nます。どれを持っているか予測できません。

LOAD DATA INFILE私の行がまたはのいずれかで終了する可能性があることを指定するために使用する方法はあります\n\r\n?どうすればこれに対処できますか?

4

7 に答える 7

11

行区切り文字を「\n」として指定し、必要に応じて、ロード中に最後のフィールドから末尾の「\r」区切り文字を削除できます。

例えば ​​-

'entries.txt'ファイルがあるとします。行区切り文字は'\r \ n'であり、行ITEM2 | CLASS3 | DATE2の後にのみ区切り文字は'\n'です。

COL1  | COL2   | COL3
ITEM1 | CLASS1 | DATE1
ITEM2 | CLASS3 | DATE2
ITEM3 | CLASS1 | DATE3
ITEM4 | CLASS2 | DATE4

CREATE TABLEステートメント:

CREATE TABLE entries(
  column1 VARCHAR(255) DEFAULT NULL,
  column2 VARCHAR(255) DEFAULT NULL,
  column3 VARCHAR(255) DEFAULT NULL
)

LOAD DATA INFILEクエリ:

LOAD DATA INFILE 'entries.txt' INTO TABLE entries
FIELDS TERMINATED BY '|'
LINES TERMINATED BY '\n'
IGNORE 1 LINES
(column1, column2, @var)
SET column3 = TRIM(TRAILING '\r' FROM @var);

結果を示す:

SELECT * FROM entries;
+---------+----------+---------+
| column1 | column2  | column3 |
+---------+----------+---------+
| ITEM1   |  CLASS1  |  DATE1  |
| ITEM2   |  CLASS3  |  DATE2  |
| ITEM3   |  CLASS1  |  DATE3  |
| ITEM4   |  CLASS2  |  DATE4  |
+---------+----------+---------+
于 2012-06-12T11:12:22.200 に答える
10

前処理するだけです。インポートプロセスの一部としてコマンドラインツールから\r\nを\nに変更するためのグローバル検索/置換は、シンプルでパフォーマンスが高い必要があります。

于 2012-06-07T16:18:31.263 に答える
3

私はあなたがどのプログラミング言語によってもmysqlを介してのみ情報を必要とすると仮定します。使用する前に、データの読み込みをWindows形式に変換してください\ r \ n(CR LF)メモ帳++がある場合。次に、データの読み込みクエリを処理します。LINESが'\r\n'で終了していることを確認してください

ここに画像の説明を入力してください

編集:

エディターは大きなファイルの変換には適さないことが多いためです。より大きなファイルの場合、次のコマンドはWindowsとLinuxの両方でよく使用されます

1)ウィンドウズでウィンドウズフォーマットに変換するには

TYPE [unix_file] | FIND "" /V > dos_file

2)LinuxでWindows形式に変換するには

unix2dos  [file]

他のコマンドも利用可能

Windows形式のファイルは、tr -d'\r'<inputfile>outputfileですべてのASCIICR \r文字を削除するだけでUnix形式に変換できます。

grep -PL $'\r\n' myfile.txt # show UNIX format  style file (LF terminated)
grep -Pl $'\r\n' myfile.txt # show WINDOS format style file (CRLF terminated)

linux / unixでは、fileコマンドは使用されたEnd-Of-Line(EOL)のタイプを検出します。したがって、このコマンドを使用してファイルタイプを確認できます

于 2012-06-12T06:47:54.547 に答える
1

また、そこにあるデータ統合パッケージの1つを調べることもできます。Talend Open Studioには、非常に柔軟なデータ入力ルーチンがあります。たとえば、1セットの区切り文字を使用してファイルを処理し、拒否をキャッチして別の方法で処理することができます。

于 2012-06-07T17:44:12.030 に答える
1

最初のロードに0行がある場合は、他の行ターミネーターで同じステートメントを実行します。これは、いくつかの基本的なカウントロジックで実行できるはずです。

少なくともそれはすべてSQLにとどまり、最初に勝ったときに機能する場合は。また、すべての行を再スキャンして特定の文字を削除するよりも頭痛の種が少なくなる可能性があります。

于 2012-06-12T21:05:59.007 に答える
1

最初に、線がどのように終わるかを覗いてみませんか?

$handle = fopen('inputFile.csv', 'r');

$i = 0;
if ($handle) {
    while (($buffer = fgets($handle)) !== false) {

        $s =  substr($buffer,-50);

        echo $s; 
        echo preg_match('/\r/', $s) ? 'cr ' : '-- ';
        echo preg_match('/\n/', $s) ? 'nl<br>' : '--<br>';          

        if( $i++ > 5)
            break;

    }

    fclose($handle);
}
于 2013-11-05T03:50:06.620 に答える
0

LINES STARTINGを使用して、テキストと新しい行の通常の行末を区切ることができます。

LOAD DATA LOCAL INFILE '/home/laptop/Downloads/field3-utf8.csv' 
IGNORE INTO TABLE Field FIELDS 
TERMINATED BY ';' 
OPTIONALLY ENCLOSED BY '^' 
LINES STARTING BY '^' 
TERMINATED BY '\r\n' 
(Id, Form_id, Name, Value)

「文字を囲む」を含む通常のCSVファイルの場合、次のようになります。

...
LINES STARTING BY '"' 
...
于 2018-07-20T07:56:03.990 に答える