Db2には外部ファイルを読み込んでバルクインサートする機能としてimportが用意されています。importはいくつかのファイル形式に対応しているのですが、もっともよく利用される形式のひとつであるCSVについて、改行を含むcsvをimportするにはどのようにすべきでしょうか?
まずCSVそのものは以下のルールにのっとるものとします。
- 行の区切りはOS依存の改行文字。つまりWindows系ならCRLF(
\r\n
)、UNIX系ならLF(\n
)。 - フィールドの区切り文字はカンマ(
,
)。 - フィールドにカンマ(
,
)、ダブルクオーテーション("
)、改行文字を含む場合は必ずそのフィールドをダブルクオーテーションで囲む。- このとき
,
は","
、"
は""
としてそれぞれエスケープする。
- このとき
基本的にはRFC4180に準拠していますが、違いは2点ほどあります。
- RFC4180では行の区切り文字をCRLFに限定するが、今回はOS依存。つまりUNIX系の場合はLFを改行文字とする。
- RFC4180では「カンマ、ダブルクオーテーション、改行文字を含まないフィールドはダブルクオーテーションで囲っても囲わなくてもよい」とするが、今回はそのようなフィールドについてはダブルクオーテーションで囲まない。
- 「
modified by chardel"
」とした場合、つまりimportのデフォルトの場合、Db2はダブルクオーテーションで囲まれたフィールドを文字列として認識するため、そのようなフィールドを数値型のカラムにimportしようとすると、失敗する場合があります。 - 要はいろいろ考えるのが面倒なだけです(´・ω・`)
- 「
このような規則にのっとり、かつフィールドに改行文字を含むCSVファイルは、たとえば以下のようにしてimportします。
import /hello/world/sample.csv of del
modified by delprioritychar
insert_update into sample_table
重要なのはdelprioritychar
オプションです。このオプションをしていしない場合、区切り文字の優先順位は以下の通りになります。
1.行の区切り文字 = 改行文字
2.文字列の区切り文字 = "
3.フィールドの区切り文字 = ,
つまり改行文字を見つけた場合、それがフィールドの一部である可能性を考えず、問答無用で行の区切り文字であると認識します。一方delprioritychar
オプションを指定すると、この優先度が次のように変化します。
1.文字列の区切り文字 = "
2.行の区切り文字 = 改行文字
3.フィールドの区切り文字 = ,
1と2が入れ替わるわけですが、これによりcsvパーサが改行文字を見つけた場合、それがフィールドの一部なのか、行の区切り文字なのかをまず考えてから処理を進めてくれます(´・ω・`)
参考: