2009年10月14日水曜日

[.NET]CSVデータを操作する(OleDb)(その3 SQLでファイルへ出力)

[.NET]CSVデータを操作する(OleDb)(その2 ファイルへ出力)では、FileのIOでソート結果をファイルに出力してみましたが、コレをOleDBを使ったSQLで実行してみました。
コードはこんな感じ。

private void button1_Click(object sender, EventArgs e)
{
    //using System.Data.OleDb;
    string csvDir = @"d:\temp";
    string csvFileName = "KEN_ALL.CSV";
    string csvOutFileName = "KEN_ALL_OUT.CSV";

    //接続文字列    
    string conString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + csvDir +
                       ";Extended Properties=\"text;HDR=No;FMT=Delimited\"";
    //OleDBでプレースホルダを使う場合はHDRが必須らしい
    string conOutString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + csvDir +
                       ";Extended Properties=\"text;HDR=Yes;FMT=Delimited\"";

    //ファイルがあったら初期化
    using (StreamWriter w = new StreamWriter(new FileStream(csvDir + @"\" + csvOutFileName, FileMode.Create))) 
    {
        w.WriteLine("F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,F13,F14,F15");
    }

    System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
    sw.Start();


    using (OleDbConnection con = new OleDbConnection(conString))
    using (OleDbConnection conOut = new OleDbConnection(conOutString))
    {
        con.Open();
        conOut.Open();

        // HDR=Noだと、Fxというフィールド名になるらしい。↓は3つめのフィールド名でソート
        string strSQL = "SELECT * FROM " + csvFileName + " ORDER BY F3";
        string strOutSQL = "INSERT INTO " + csvOutFileName + " VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        using (OleDbCommand cmd = new OleDbCommand(strSQL, con))
        using (OleDbDataReader rd = cmd.ExecuteReader())
        using (OleDbCommand cmdOut = new OleDbCommand(strOutSQL, conOut))
        {
            //カラムの属性から、SQLパラメータを作成する
            for (int col = 0; col < rd.FieldCount; col++)
            {
                cmdOut.Parameters.Add(new OleDbParameter(rd.GetName(col), rd.GetFieldType(col)));
            }

            //データを取得しカンマ区切りで編集します
            while (rd.Read())
            {
                for (int col = 0; col < rd.FieldCount; col++)
                {
                    cmdOut.Parameters[col].Value = rd.GetValue(col);
                }
                cmdOut.ExecuteNonQuery();
            }

        }
    }
    sw.Stop();
    label1.Text=  String.Format("完了{0:#,##0}ms", sw.ElapsedMilliseconds);
}
}


・・・実行して1時間ほど放置してみましたが終わりませんでした。で強制終了させてみると、2万件ほどデータが出力されていました。
しかも、すべてのフィールドがテキスト形式として保存されていました。型指定で手抜きしたせいだろうか。。。

パフォーマンス的な話で言えば、OleDBのCSVに対するINSERTは実用的ではありませんね。

0 件のコメント: