.Net1.1 では、DataTable 全体のすべてのデータをデータベースにバッチ挿入したり、異なるデータ ソース間で移行したりするのはあまり便利ではありません。 .Net2.0 では、DataTable または DataReader を介してデータをバッチで移行できるように、SQLClient 名前空間の下にいくつかの新しいクラスが追加されました。データ ソースは、リレーショナル データベースや XML ファイル、あるいは WebService によって返された結果から取得することもできます。最も重要なクラスの 1 つは SqlBulkCopy クラスです。これは、データ ソースからターゲット データベースにデータを簡単に移行するのに役立ちます。
まず、簡単な例を通してこのクラスの使用法を説明しましょう。
日付時刻開始時刻;
protected void Button1_Click(オブジェクト送信者、EventArgs e)
{
startTime = DateTime.Now;
文字列SrcConString;
文字列 DesConString;
SqlConnection SrcCon = 新しい SqlConnection();
SqlConnection DesCon = new SqlConnection();
SqlCommand SrcCom = new SqlCommand();
SqlDataAdapter SrcAdapter = new SqlDataAdapter();
DataTable dt = 新しい DataTable();
SrcConString =
ConfigurationManager.ConnectionStrings["SrcDBConnectionString"].ConnectionString;
DesConString =
ConfigurationManager.ConnectionStrings["DesDBConnectionString"].ConnectionString;
SrcCon.ConnectionString = SrcConString;
SrcCom.Connection = SrcCon;
SrcCom.CommandText = " SELECT * [SrcTable] から";
SrcCom.CommandType = CommandType.Text;
SrcCom.Connection.Open();
SrcAdapter.SelectCommand = SrcCom;
SrcAdapter.Fill(dt);
SqlBulkCopy DesBulkOp;
DesBulkOp = new SqlBulkCopy(DesConString,
SqlBulkCopyOptions.UseInternalTransaction);
DesBulkOp.BulkCopyTimeout = 500000000;
DesBulkOp.SqlRowsCopied +=
新しい SqlRowsCopiedEventHandler(OnRowsCopied);
DesBulkOp.NotifyAfter = dt.Rows.Count;
試す
{
DesBulkOp.DestinationTableName = "SrcTable";
DesBulkOp.WriteToServer(dt);
}
catch (例外例)
{
lblResult.Text = ex.Message;
}
ついに
{
SrcCon.Close();
DesCon.Close();
}
private
void OnRowsCopied(オブジェクト送信者, SqlRowsCopiedEventArgs args)
{
lblCounter.Text += args.RowsCopied.ToString() + " 行がコピーされます<Br>";
TimeSpan copyTime = DateTime.Now - startTime;
lblCounter.Text += "コピー時間:" + copyTime.Seconds.ToString() + "." + copyTime.Milliseconds.ToString() + " 秒";
}
次に、次のコード行を詳細に分析します。
SqlBulkCopy DesBulkOp;
DesBulkOp = new SqlBulkCopy(DesConString, SqlBulkCopyOptions.UseInternalTransaction); まず、SqlBulkCopyOptions.UseInternalTransaction を使用して、コンストラクターで移行アクションがトランザクションで指定されることを意味します。ロールバックが発生します。他のオプションについては MSDN を参照してください。
DesBulkOp.BulkCopyTimeout = 500000000;
操作完了のタイムアウト時間を指定します
DesBulkOp.SqlRowsCopied += new SqlRowsCopiedEventHandler(OnRowsCopied);
DesBulkOp.NotifyAfter = dt.Rows.Count;
試す
{
DesBulkOp.DestinationTableName = "SrcTable";
DesBulkOp.WriteToServer(dt);
}
NotifyAfter 属性は、通知イベントの前に処理されるデータ行数を指定します。ここではテーブル内の行数として指定され、移行プロセス全体の時間を出力するために SqlRowsCopied イベントが追加されます。 WriteToServer メソッドは、データ ソースをターゲット データベースにコピーします。 WriteToServer メソッドを使用する前に、まず DestinationTableName 属性を指定する必要があります。これはターゲット データベースのテーブル名です。
たとえば、次のようにトランザクションを定義することもできます
。
トランザクション =
SrcCom.Connection.BeginTransaction();
SqlBulkCopy DesBulkOp;
DesBulkOp = new SqlBulkCopy(new SqlConnection(DesConString),
SqlBulkCopyOptions.Default、
トランザクション
);
{
//..
}
キャッチ{}
ついに
{
Transaction.Commit();
}
データ ソース フィールドをターゲット データ内の異なる名前のフィールドにマップできるようにする SqlBulkCopyColumnMapping クラスもあります。つまり、ターゲット データとソース データの列名が異なる場合、このクラスをマッピングに使用できます。
SqlBulkCopyColumnMapping ColMap = new SqlBulkCopyColumnMapping("SrcCol", "DesCol");
DesBulkOp.ColumnMappings.Add(ColMap);
または、マッピングを直接追加することもできます。
DesBulkOp.ColumnMappings.Add("SrcCol", "DesCol");
パフォーマンスの問題:
上記の例を使用して約 20,000 レコードをテストしましたが、所要時間は 1 秒もかかりませんでした。パフォーマンスは依然として良好です。さらに、SQL プロファイルを使用して移行イベントを監視すると、要求レコードが非常に少なく、わずか数件しかないことがわかります。 SqlBulkCopyを利用することでデータ移行の時間を大幅に短縮できると言われています。