SqlBulkCopy是.NET的一個類常用於批量插入數據,這種方式比Insert方式性能要高許多。
需要注意的是,DataTable中的列需要與即將插入的表的列兼容,名稱和數據庫的順序完全一致。樓主往日期類型插入空值時就遇到了一個問題,那就是不能給這一列的設置Null值,而是要通過不給其賦值的方式。DataTable的表名要與數據庫的表名一致。
插入數據時,有個SqlBulkCopyOptions可以設置,它可以更改SqlBulkCopy的行爲,它是枚舉類型,它的值如下所示:
字段 |
解釋 |
Default |
使用所有選項的默認值 |
KeepIdentity |
保留源標識值。 未指定標識值時,該值由目標指派。這個很好理解,比如將A表中的數據批量導入到B表中,B表的標識列id依舊套用A表的id時就需要這個。 |
CheckConstraints |
插入數據時檢查約束。 默認情況下,不檢查約束。當數據是從外部導入時就需要檢查約束 |
TableLock |
獲取批量複製操作持續時間的批量更新鎖定。 如果未指定,則使用行鎖定。 |
KeepNulls |
在目標表中保留 null 值,而不考慮默認值的設置。 如果未指定,由默認值替換 null 值(適用時)。假如A表中的Salary爲Null,B表中的Salary的默認值爲0,那麼A表導入B表後Salary的值會變成0。 |
FireTriggers |
如果指定,則使服務器激發插入觸發器,從而使行插入數據庫。 |
UseInternalTransaction |
如果指定,批量複製操作的每一批都將在事務內發生。如果指示該選項,並且還向構造函數提供 SqlTransaction 對象,則發生 ArgumentException。 |
示例代碼如下:
/// <summary>
/// 批量導入
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public static bool ExecuteNonQuery(DataTable dt)
{
SqlConnection connection = null;
SqlTransaction tran = null;
SqlBulkCopy sqlbulkcopy = null;
try
{
connection = new SqlConnection(connStr);
connection.Open();
tran = connection.BeginTransaction();//開啓事務
sqlbulkcopy = new SqlBulkCopy(connection, SqlBulkCopyOptions.CheckConstraints, tran);
sqlbulkcopy.BulkCopyTimeout = 100; //超時之前操作完成所允許的秒數
sqlbulkcopy.BatchSize = dt.Rows.Count; //每一批次中的行數
sqlbulkcopy.DestinationTableName = dt.TableName; //服務器上目標表的名稱
for (int i = 0; i < dt.Columns.Count; i++)
{
sqlbulkcopy.ColumnMappings.Add(i, i); //映射定義數據源中的列和目標表中的列之間的關係
}
sqlbulkcopy.WriteToServer(dt); // 將DataTable數據上傳到數據表中
tran.Commit();
return true;
}
catch (Exception e)
{
if (connection != null)
{
connection.Close();
}
tran.Rollback();
return false;
}
finally
{
if (connection != null)
{
connection.Close();
}
if(sqlbulkcopy != null)
{
sqlbulkcopy.Close();
}
}
}
來源:使用事務和SqlBulkCopy批量插入數據 SqlBulkCopyOptions Enum