[.NET] Oracle Bulk Insert

  • 1513
  • 0
  • 2016-09-12

Oracle Bulk Insert Using .Net

假設有一 Product 類別 

public class Product
 {	 
	public int ProductId {get;set;}
	public string Name {get;set;}
	public string EngName {get;set;} 	
 }

重點一:設定 ArrayBindCount,告訴 command 總共要寫入幾筆資料

var conn = CreateConnection() as OracleConnection;
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = GetSql();
cmd.CommandType = CommandType.Text;
cmd.BindByName = true;
cmd.ArrayBindCount = entitiesToInsert.Count;

重點二:參數的資料傳 Array 作為引數,並且設定 OracleDbType 與 ParameterDirection

command.Parameters.Add(":ProductId", OracleDbType.Number, entitiesToInsert.Select(c => c.ProductId).ToArray(), ParameterDirection.Input);
command.Parameters.Add(":Name", OracleDbType.Varchar2, entitiesToInsert.Select(c => c.Name).ToArray(), ParameterDirection.Input);
command.Parameters.Add(":EngName", OracleDbType.Varchar2, entitiesToInsert.Select(c => c.EngName).ToArray(), ParameterDirection.Input);

int result = command.ExecuteNonQuery();
conn.Dispose();

if (result != entitiesToInsert.Count)
{
    throw new OracleException("Oops! 實際寫入資料庫筆數與欲寫入筆數不一致");
}

使用起來效能差滿多的,以往使用一筆一筆 Insert 的方式, 25000 筆資料大概要 1 分鐘,

就算 100, 1000 筆 commit 並重建 connection 也快不了多少,但使用上述方式後只要 2 秒就可完成!

參數可以用 Reflection 來處理,不然 Table 欄位很多時,寫一堆 cmd.Parameters.Add(..., ...) 非常浪費生命

如果還不會用 Reflection,資料量少時還是使用 ORM 提供的方法一筆筆寫入比較省時,而當資料量大且需要考量效能時再用 Bulk Insert 就好。