一括挿入 (バルクインサート) を利用してデータベースに高速にレコードを挿入する - C#

C#で一括挿入 (バルクインサート) を利用してデータベースに高速にレコードを挿入するコードを紹介します。

概要

データベースのテーブルに大量のレコードを高速に挿入する方法として一括挿入(バルクインサーション)という方法があります。 この記事では、C#を利用して一括挿入をするコードを紹介します。

プログラム

Windows Formアプリケーションを作成します。

UI

下図のUIを作成します。フォームにボタンと複数行のテキストボックスを配置します。

コード

下記のコードを記述します。
ボタンのクリックイベントを実装し、CreateDataTable() と BulkInsert() メソッドを記述します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace BulkInsertDemo
{
  public partial class FormBulkInsert : Form
  {
    public FormBulkInsert()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      var dt = CreateDataTable();
      var connectionString = "Data Source=192.168.0.1;Initial Catalog=iPentecSandbox;Connect Timeout=60;Persist Security Info=True;User ID=user;Password=*********;";
      BulkInsert(connectionString, dt);

      textBox1.Text = "テーブルを作成して、レコードを挿入しました。";
    }

    private DataTable CreateDataTable()
    {
      DataTable dt = new DataTable();
      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);
      DataColumn dcPrice = new DataColumn("Price", Type.GetType("System.Int"));
      dt.Columns.Add(dcPrice);

      DataRow row1 = dt.NewRow();
      row1.BeginEdit();
      row1["Code"] = "P-001";
      row1["Name"] = "ぺんぎんクッキー";
      row1["Price"] = 150;
      row1.EndEdit();
      dt.Rows.Add(row1);

      DataRow row2 = dt.NewRow();
      row2.BeginEdit();
      row2["Code"] = "P-002";
      row2["Name"] = "しろくまアイス";
      row2["Price"] = 260;
      row2.EndEdit();
      dt.Rows.Add(row2);

      DataRow row3 = dt.NewRow();
      row3.BeginEdit();
      row3["Code"] = "P-003";
      row3["Name"] = "らくだキャラメル";
      row3["Price"] = 150; row3.EndEdit();
      dt.Rows.Add(row3);
      return dt;
    }

    private void BulkInsert(string connectionString, DataTable dt)
    {
      SqlConnection con = new SqlConnection(connectionString);
      SqlBulkCopy bc = new SqlBulkCopy(con);
      bc.DestinationTableName = "MyNewTable";
      try {
        con.Open();
        bc.WriteToServer(dt);
      }
      finally {
        con.Close();
      }
    }
  }
}

解説

ボタンをクリックすると、CreateDataTableメソッドを呼び出します。CreateDataTableメソッドでは一括挿入するためのレコードセットを作成します。 作成されたレコードセットは、DataTableオブジェクトとして返します。
DataTableオブジェクトのレコードセットをデータベースに挿入する処理がBulkInsertメソッドです。 BulkInsertメソッドには、データベースへの接続文字列とDataTableオブジェクトを与えます。
処理が完了すると、テキストボックスにメッセージを表示します。
  DataTable dt = CreateDataTable();
  string connectionString = "Data Source=192.168.0.1;Initial Catalog=iPentecSandbox;Connect Timeout=60;Persist Security Info=True;User ID=user;Password=*********;";
  BulkInsert(connectionString, dt);

  textBox1.Text = "テーブルを作成して、レコードを挿入しました。";

CreateDataTableメソッドで、一括挿入するためのDataTableオブジェクトを作成します。
DataTableオブジェクトを作成し、挿入するレコードの列のDataColumnオブジェクトを作成します。DataColumnオブジェクトの列名はデータベースのテーブルの挿入列名と同じにします。
挿入するレコードは、DataTableオブジェクトのNewRow()メソッドを呼び出し、DataRowオブジェクトを作成します。
作成したDataRowオブジェクトのBeginEdit()メソッドを呼び出し編集状態にします。挿入する値はDataRowの挿入する名称の名前付きインデックス(インデクサ)に代入して設定します。
値の代入後EndEdit()メソッドを呼び出し編集を終了します。DataRowオブジェクトをDataTableのRowsオブジェクトにAdd()メソッドを呼び出して挿入します。
同様の処理を繰り返し挿入する複数のレコードを準備します。
private DataTable CreateDataTable()
{
  DataTable dt = new DataTable();
  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);
  DataColumn dcPrice = new DataColumn("Price", Type.GetType("System.Int"));
  dt.Columns.Add(dcPrice);

  DataRow row1 = dt.NewRow();
  row1.BeginEdit();
  row1["Code"] = "P-001";
  row1["Name"] = "ぺんぎんクッキー";
  row1["Price"] = 150;
  row1.EndEdit();
  dt.Rows.Add(row1);

  DataRow row2 = dt.NewRow();
  row2.BeginEdit();
  row2["Code"] = "P-002";
  row2["Name"] = "しろくまアイス";
  row2["Price"] = 260;
  row2.EndEdit();
  dt.Rows.Add(row2);

  DataRow row3 = dt.NewRow();
  row3.BeginEdit();
  row3["Code"] = "P-003";
  row3["Name"] = "らくだキャラメル";
  row3["Price"] = 150;
  row3.EndEdit();
  dt.Rows.Add(row3);
  return dt;
}

BulkInsertメソッドで、先に作成したDataTableオブジェクトをデータベースに挿入します。
SqlConnectionオブジェクトを作成します。コンストラクタの引数には、データベース接続文字列を与えます。
また、一括挿入するための、SqlBulkCopyオブジェクトを作成します。SqlCulkCopyオブジェクトのDestinationTableNameに挿入先のテーブル名を設定します。
SqlConnectionオブジェクトのOpen()メソッドを呼び出し、接続を開き、SqlBulkCopyオブジェクトのWriteToServer()メソッドを呼び出して一括挿入を実行します。
処理が終了したらSqlConnectionオブジェクトを閉じます。
private void BulkInsert(string connectionString, DataTable dt)
{
  SqlConnection con = new SqlConnection(connectionString);
  SqlBulkCopy bc = new SqlBulkCopy(con);
  bc.DestinationTableName = "MyNewTable";
  try {
    con.Open();
    bc.WriteToServer(dt);
  }
  finally {
    con.Close();
  }
}

テーブルの準備

レコードを挿入するテーブルを作成します。MyNewTableという名称でテーブルを作成します。列名はCode Name Price の列を用意します。

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。


[button1]をクリックします。クリックすると処理が実行され、テキストボックスにメッセージが表示されます。


テーブルのレコードを確認します。テーブルのレコード一覧を表示します。コードで記述した値のレコードが挿入されていることが確認できます。

もう一度実行した場合

[button1]をもう一度クリックします。


同じ値のレコードが追加されることが確認できます。


著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2023-05-02
作成日: 2020-07-28
iPentec all rights reserverd.