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という方法もある。

ただファイル出力などの手間があるので今回は見送り。




いいなと思ったら応援しよう!