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 就好。