C#備忘録
Oracleから取得したデータをDataTableでMySQLへBulk Insert
通常はSQL Serverのみだが、NuGetでZ.BulkOperationsをインストールすれば簡単にDataTableを使用してBulk Insert可能。
public void Insert(DataTable tbl)
{
var bulk = new BulkOperation(msConn);
oraTbl.TableName = biTbName;
bulk.BulkInsert(oraTbl);
}
Bulk Insertを使用するにあたって注意が必要なのは2つ。
・テーブル名が一致していること
・カラム名が一致していること
Oracleから取得したデータを元にSQLを組み立ててMySQLへBulk Insert
こちらは特にインストールせずに実行可能。
簡単に言うとOracleから取得したレコード文Insertとするのとほぼ変わらないが、Valuesをある程度設定してからInsertする。
1行ずつInsertするよりはコストがかからない。
public void Insert(DataTable tbl)
{
//インサートするvaluesを保持
List<string> Rows = new List<string>();
//Insert文
var insSql = " INSERT INTO TMP_TBL ( COL1, COL2, COL3, COL4) VALUES ";
var insValSql = "('{0}', '{1}', '{2}', {3})";
//DataTableのレコード分繰り返す
for (var i = 0; i < tbl.Rows.Count; i++)
{
DataRow row = tbl.Rows[i];
//Values以降を作成
Rows.Add(string.Format(insValSql,
MySqlHelper.EscapeString(row[0].ToString()),
MySqlHelper.EscapeString(row[1].ToString()),
MySqlHelper.EscapeString(row[2].ToString()),
MySqlHelper.EscapeString(row[3].ToString()));
//1万件になったらInsert
if ((i + 1) % 10000 == 0)
{
command.CommandText = insSql + string.Join(",", Rows) + ";";
// 実行
command.ExecuteNonQuery();
Rows = new List<string>();
}
//最終レコードになったらInsert
else if (i + 1 == tbl.Rows.Count)
{
command.CommandText = insSql + string.Join(",", Rows) + ";";
// 実行
command.ExecuteNonQuery();
Rows = new List<string>();
}
}
}
必要になったので対応したけど、もっと高速でやるのであればLOAD DATA INFILEという方法もある。
ただファイル出力などの手間があるので今回は見送り。