2011-01-13 21 views
9

.csvファイルをMySQLにインポートしていますが、ファイル内の改行を除いてすべて正常に動作します。私の.csv行のCSVからMySQLへの改行問題

一つは次のようになります。

42,E-A-R™ Classic™ Earplugs,ear,images/ear/classic.jpg,5%,"Proven size, shape, and foam 
3M's most popular earplug 
Corded and uncorded in a variety of individual packs 
NRR 29 dB/CSA Class AL",312-1201,,"E-A-R™ Classic™ Uncorded Earplugs, in Poly Bag",310-1001,,E-A-R™ Classic™ Uncorded Earplugs in Pillow Pack,311-1101,,"E-A-R™ Classic™ Corded Earplugs, in Poly Bag" 

6番目のフィールドの上に呼び出されたときに、新しいラインに侵入、それはないはずです。 .csvをインポートするときは、行をで終了します。私は\ nと自動しかし、運を試してみました。

奇妙なことは、データベース内の適切なブレークがすべて正しく表示されていることです。 PHPmyadminで手動で改行を挿入すると正しく印刷されます。各フィールドはUTF-8にも設定されています。

これに関するご意見はありますか?ありがとう。

編集:ここではMySQLの文がある

LOAD DATA LOCAL INFILE '/tmp/php89FC0F' REPLACE INTO TABLE `ohes_flyer_products` 
FIELDS TERMINATED BY ',' 
ENCLOSED BY '"' 
ESCAPED BY '\\' 
LINES TERMINATED BY '\r' 
+0

最初にインポートしようとしているものは、phpMyAdminまたはconsole mysqlですか? –

+0

"Proven size"で始まる6番目のフィールドを意味すると仮定します。 – JYelton

+1

使用する正確なMySQL LOAD DATAステートメントを投稿できますか? – Tomalak

答えて

3

多分あなたは配列に各CSVの行を解析するためにfgetcsvを使用して、データベースにその配列をダンプだろうか?

$fd = fopen($csvfile, "r"); 
while ($line = fgetcsv($fd)) 
{ 
    $sql = sprintf("INSERT INTO tablename (...) VALUES ('%s', ...)", $line[0], ...); 
    $res = mysql_query($sql); 
} 

ノート1の線に沿って

何か:生産のためのコードの準備ができていませんが、SQLインジェクションをチェック!

注2:準備された文を使用すると、多くの処理が高速化されます(または複数行の挿入文が作成されます)。

注3:トランザクションですべてをラップします。

0

あなたのCSVは、非標準的なように見えるが、それは多くの場合、顧客のデータセットを扱うの現実です。

MySQLのLOAD DATAステートメントのようなツールは完璧なユースケースのみを扱うため、このような非標準データセットを扱うにはコードが必要であることがわかりました。

これを処理する1つの方法は、最初にCSVをスクラブし、中間フィールドの改行を特殊な一意の文字列(たとえば===MIDFIELD_LINE_BREAK===)に置き換えることです。それから私はスクリプト言語(Python、Ruby、PHP、Perlなど)でカスタムCSVパーサーを作成します。

CSVパーサーでは、ファイル内の行を繰り返し処理します。各行について:

  • バック===MIDFIELD_LINE_BREAK===文字の中\nまたは\r文字を入れ替えます。
  • INSERT文を作成して実行します。
+0

それはうまくいくように聞こえますが、それでも手作業で=== MIDFIELD_LINE_BREAK ===を入力する必要があります。代わりに私は手動で\ nを入力したように見えます。とにかく、ありがとう。 – Carson

+0

「スクラブ」と言ったとき、ルールベースの自動スクラブ(つまり、「アンエスケープされていない/コンマがないコンマがあるまで次の行に参加する」)を指定する必要がありました。私はあなたのデータセットが手動でこすり落とすのに十分小さかったのか分からなかったが、うまくいきました。 –

7
LOAD DATA LOCAL INFILE '/tmp/php89FC0F' REPLACE INTO TABLE `ohes_flyer_products` 
FIELDS TERMINATED BY ',' 
OPTIONALLY ENCLOSED BY '"' 
ESCAPED BY '\\' 
LINES TERMINATED BY '\r\n' 
+0

ENCLOSED BYの前にOPTIONALLYを追加して問題を解決することが重要だった – miguelfg

1

あなたのCSVファイルには、活用することができるかもしれないいくつかの資質を持っています。

  • ないレコードを終了ないキャリッジリターンを含むフィールドは、引用符で囲まれています。
  • レコードの末尾を示すキャリッジリターンは、データが引用符で囲まれたレコードの後に​​続きます。これがすべてのレコードに当てはまる場合は、おそらくミッドフィールドキャリッジリターンをレコードターミネータと区別するための方法です。

これを知って、ここでいくつかのものは、あなたが試すことができます:

UltraEdit(またはメモ帳++)とその検索のように/(正規表現の取り扱いを含め)の機能を置き換えるプログラムを使用して

    • 引用符で始まるキャリッジリターンをすべて検索し、一意の文字または文字列で置き換えます。私はパイプ文字 "|" CSVファイル内のどこでも使用されていないことを確認してください。これらはレコードの終わりを表します。
    • 次に、すべてのキャリッジリターンをスペースで置き換えます。これにより、不要なキャリッジリターンのフィールドが他のデータとの位置合わせに戻ります。
    • 最後に、すべての特殊なend-of-record文字をキャリッジリターンに置き換えます。唯一のキャリッジリターンが存在する最終的な結果は、記録終了指示器である。キャリッジリターンはインポートエンジンが唯一のフィールドを尊重すべきであり、レコードが引用の外デリミタように指定することができ、区切り文字(引用符)で囲まれたフィールド内に表示されていることを考えると
  1. 。 (MySQL LOAD DATA INFILE syntax)具体的には、ENCLOSED BY 'char'パラメータを見てください。すべてのフィールドが区切り文字を使用するわけではないので、OPTIONALLYを指定する必要があります。理論的には、CSVファイルの構築方法を指定することができ、事前に解析する必要はありません。しかし、新しい文脈での出力時にテキストが適切に折り返されるように、フィールド内のキャリッジリターンはおそらく削除されるべきだと私は考えています。

0

これが私の仕事:

$query = <<<EOT 

LOAD DATA LOCAL INFILE '$file' REPLACE INTO TABLE `$table` 
FIELDS TERMINATED BY ',' 
OPTIONALLY ENCLOSED BY '"' 
ESCAPED BY '\\\' 
LINES TERMINATED BY '\\\n' 
IGNORE 1 ROWS; 

EOT; 

を私はいくつかの余分なフォワードスラッシュを追加することで、起因するエラーを取得し、Krunalの答え@微調整する必要がありました。

ここでは、UNIXラインリターンを使用しています。

​​
関連する問題