【C#】【SQL Server】SqlBulkCopy ~高速に大量データを挿入するには~

■ 用途

 * SQL Serverのテーブルにデータを一括で読み込むことができる
 * しかも高速で。パフォーマンス向上に役立つ。(詳細は以下を参照のこと)
http://d.hatena.ne.jp/re_guzy/20060108/p1
http://www.moonmile.net/blog/archives/2234

■ 欠点

 * 書き込み先が、SQL Serverのみ(他のDBでは使用できない)
 * INSERTしかできない(同じPKのレコードがあると制約違反にな)
http://www.souya.biz/blog/2009/12/21/sqlserver%E9%96%93%E3%81%A7%E5%A4%A7%E9%87%8F%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E9%AB%98%E9%80%9F%E5%90%8C%E6%9C%9F/
 * Decimal 型で桁落ちをする(詳細は以下を参照のこと)
http://www.moonmile.net/blog/archives/2426

■ 使用上の注意

 * 引数がDataTableなので、DataTable のメモリ溢れに注意する必要がある
 →SqlBulkCopyを敢えて使うのであれば、大容量データを扱う事が多いと思うので、
  実行環境のメモリを考慮しながら、実装すべき。
 →DataTable の解放処理も忘れずに。

■ サンプル

private void button1_Click(object sender, EventArgs e)
{
    var dt = this.CreateDataTable();

    var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings[
        "XxxxxConnectionString"].ConnectionString;
    this.BulkInsert(connectionString, dt);
}

private void BulkInsert(string connectionString, System.Data.DataTable dt)
{
    // ★ここに注目★
    using (SqlConnection cn = new SqlConnection(connectionString))
    {
        SqlBulkCopy bc = new SqlBulkCopy(cn);
        bc.DestinationTableName = "Brunch";
        cn.Open();
        bc.WriteToServer(dt);
    }
}

private System.Data.DataTable CreateDataTable()
{
    var dt = new System.Data.DataTable();

    DataColumn dcCompanyCode =
        new DataColumn("CompanyCode", Type.GetType("System.String"));
    dt.Columns.Add(dcCompanyCode);
    DataColumn dcCode =
        new DataColumn("Code", Type.GetType("System.String"));
    dt.Columns.Add(dcCode);
    DataColumn dcName =
        new DataColumn("Name", Type.GetType("System.String"));
    dt.Columns.Add(dcName);

    var row1 = dt.NewRow();
    row1.BeginEdit();
    row1["CompanyCode"] = "C003";
    row1["Code"] = "B301";
    row1["Name"] = "Brunch-301";
    row1.EndEdit();
    dt.Rows.Add(row1);

    var row2 = dt.NewRow();
    row2.BeginEdit();
    row2["CompanyCode"] = "C004";
    row2["Code"] = "B401";
    row2["Name"] = "Brunch-401";
    row2.EndEdit();
    dt.Rows.Add(row2);

    var row3 = dt.NewRow();
    row3.BeginEdit();
    row3["CompanyCode"] = "C004";
    row3["Code"] = "B402";
    row3["Name"] = "Brunch-402";
    row3.EndEdit();
    dt.Rows.Add(row3);

    return dt;
}



関連記事

バルク・インサート ~Bulk Insert~

http://blogs.yahoo.co.jp/dk521123/30372192.html