MTU lab

文字列に改行を含むCSVのロード(2/2)

準備

  1. マイクロソフト社のVisual C++ 2013 以降の製品を用意してください。Visual C++ の Community エディションであれば こちらから入手できます。
  2. 変換プログラムの入った書庫ファイルをこちらからダウンロードして任意のフォルダへ解凍してください。
  3. ※本稿で提供するソフトウエアの著作権は株式会社プラムシックスが所有します。このソフトウエアを取り扱う際は MIT License に定められた条項を遵守するものとします。
  4. Visual Studio の製品のメニューに含まれる「Visual Studio コマンド プロンプト」を表示し、変換プログラムを解凍した場所へ移動します。
  5. cd /d 変換プログラムのフォルダ名
  6. コマンドプロンプトからnmakeコマンドを発行してプログラムをビルドします。
  7. nmake EXE="addlength.exe" OBJS="addlength.obj" CPPFLAGS="/nologo /EHsc /Zi /O2"
  8. 以上で準備が整いました。

実行

  1. 次のコマンドをコマンドプロンプトから入力してプログラムを実行します。
  2. addlength src_file dst_file
    ここで src_file は変換前、dst_file は変換後のファイルを示します。ファイル名の前にフォルダ名を追加することが出来ます。フォルダ名を省略するとカレントフォルダを変換対象とします。
  3. 実際に変換を試した事例です。
  4. c:\github\addlength>addlength LOAD_SAMPLE.csv LOAD_SAMPLE.dat
    Infomation - Completed successfully. Wrote 3 records and 130 bytes in 0.00 seconds.
    
    c:\github\addlength>type LOAD_SAMPLE.csv
    "2012/10/21","改行無し",85
    "2012/11/21","2文
    字目で改行",86
    "2012/11/21","4文字目
    で改行",87
    
    c:\github\addlength>type LOAD_SAMPLE.dat
    0000000029"2012/10/21","改行無し",85,
    0000000037"2012/11/21","2文
    字目で改行",86,
    0000000037"2012/11/21","4文字目
    で改行",87,
    
  5. レコード形式がストリーム形式から可変レコード形式へ変更されたので、制御ファイルを書き換えます。また、変換した結果ファイル名が LOAD_SAMPLE.dat へ変わったのでその内容も反映させます。
  6. c:\github\addlength>type LOAD_SAMPLE.ctl
    LOAD INFILE "LOAD_SAMPLE.dat" "VAR 10"
    INTO TABLE "LOAD_SAMPLE"
    TRUNCATE FIELDS TERMINATED BY ','
    TRAILING NULLCOLS
    (  "C1" DATE "YYYY/MM/DD" ENCLOSED BY '"'
    ,  "C2" CHAR ENCLOSED BY '"'
    ,  "C3" DECIMAL EXTERNAL
    )
    
  7. それでは変換したデータをSQL*Loader をつかってロードできるかどうか確認してみましょう。
  8. c:\github\addlength>sqlldr SCOTT/TIGER control=LOAD_SAMPLE
    
    SQL*Loader: Release 11.2.0.1.0 - Production on 金 10月 26 18:02:52 2012
    
    Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.
    
    コミット・ポイントに達しました。 - 論理レコード件数3
    
  9. テーブルにデータが保存されたかどうかSQL*Plus で確認してみます。
  10. c:\github\addlength>sqlplus SCOTT/TIGER
    
    SQL*Plus: Release 11.2.0.2.0 Production on 月 10月 29 17:48:37 2012
    
    Copyright (c) 1982, 2010, Oracle.  All rights reserved.
    
    
    
    Oracle Database 11g Express Edition Release 11.2.0.2.0 - Production
    に接続されました。
    SQL> COLUMN C2 FORMAT A10
    SQL> select * from LOAD_SAMPLE;
    
    C1       C2                 C3
    -------- ---------- ----------
    12-10-21 改行無し           85
    12-11-21 2文               86
             字目で改行
    
    12-11-21 4文字目           87
             で改行
    
    
    SQL>
    

    無事、ロードすることが出来ました。

まとめ

このトピックを通じて次のことが分かりました。

  1. SQL*Loader がサポートするレコード形式のうちストリーム・レコード形式は文字列型フィールド内に改行コードが含まれると正しくロードできない。しかもこれが省略時初期値である。
  2. CSVを作り直しすることなく、データをロードするには可変レコード形式へデータ変換する必要がある。
  3. データ変換後は各レコードごとに先頭へnバイト固定幅のレコード長、末尾(CF+LFの直前)にカンマ文字が配置されるようにする。但し行数が多い場合は変換プログラムの助けが必要。
  4. 制御ファイルにも修正を加える。INFILE 句へ “VAR n” というオプションを加える。

尚、提供したデータ変換プログラム:addlength.cpp は、Shift-JISの他UTF-8に対応(自動識別)し、大量データでも実用に堪える性能を備えています。
性能を調査した結果以下の通りでした。使用したハードウエアは製品紹介のテストで使用したものと同じです。

指標 数値
行数 1億件
バイト数 4.7GB
所要時間 95秒
データ率 50.1MB/秒
c:\github\addlength>addlength output\F1.dat output\F1.csv
Infomation - Completed successfully. Wrote 100000000 records and 5161887577 bytes in 95.04 seconds.

上記はテスト時の画面のハードコピーです。

ところでMTUには、事前に改行コードを含む文字列があると分かっている場合は、今回の事例に示したような可変レコード形式の制御ファイルと、データ長入りのCSVデータを出力できるようになっています。
アンロード前に改行入り文字列型データの状況は分からないことが多いため、ストリーム・レコード形式ではなく可変レコード形式で出力する設定が、製品の出荷時初期値として設定されています。固定レコード形式も選択可能です。
この動作を制御する環境変数は RECLENGTH です。env.bat ファイル中に定義されています。

by 開発1号

文字列に改行を含むCSVのロード(1/2)へ戻る