2016-04-19 41 views
0

我正在查看使用SqlDataAdapter執行批量插入操作的一些較舊的數據訪問代碼。目標表有一個主鍵約束,我需要識別任何我嘗試插入的行,這些行違反了這個主鍵(即檢測重複項)並對這些行執行操作。ADO.net SqlDataAdapter.Update批量插入如何檢測主鍵違規?

大多數時候,插入將不是有任何重複,但我確實需要處理的情況下,當有。通過實驗發現,進行批量插入然後查找違規更快,在添加之前單獨檢查每行是否存在。

執行此操作的代碼如下所示。

foreach (DataTable dataTable in dataSet.Tables) 
    { 
    try 
    { 
     List<string> columns = new List<string>(); 
     foreach (DataColumn column in dataTable.Columns) 
     columns.Add(column.ColumnName); 

     string commandText = "select " + String.Join(",", columns.ToArray()) + " from " + dataTable.TableName; 

     SqlCommand sqlCommand = new SqlCommand(commandText, conn); 
     SqlDataAdapter dataAdapter = new SqlDataAdapter(sqlCommand); 
     dataAdapter.ContinueUpdateOnError = true; 
     SqlCommandBuilder sqlBuilder = new SqlCommandBuilder(dataAdapter); 
     dataAdapter.Update(dataTable); 

    } 
    catch (Exception) 
    { 
     // No exception should be thrown with ContinueUpdateOnError = true 
    } 
    } 

    return dataSet; 

注意dataAdapter.ContinueUpdateOnError = true;意味着任何錯誤不會引發任何異常(異常塊是從未進入)

所以,一旦上面已經運行,我們可以尋找任何錯誤,包括任何主鍵衝突,使用如下代碼...

foreach (DataTable dataTable in dataSet) 
{ 
    foreach (DataRow dataRow in dataTable.Rows) 
    { 
     if (dataRow.HasErrors) 
     { 
      // Here I want to detect if the error was a primary key violation, or something else 
     } 
    } 
} 

所以,我可以檢測到有通過如上.HasErrors某種錯誤的行,但我看不出一個好辦法檢測到這個錯誤是主要違規行爲。有一個RowError屬性,但是這僅僅是文字像... Violation of PRIMARY KEY constraint 'PK_MYKEY'. Cannot insert duplicate key in object 'dbo.MY_TABLE'. The duplicate key value is (6215). The statement has been terminated.

我可以看到一些其他錯誤區分開的唯一途徑(如磁盤錯誤等)是通過搜索一些上面的文本,但這似乎不是很健壯或良好的做法(錯誤文本可能會改變,或者如果運行不同的語言/文化,文本也將是不同的)

dataRow也有一個ErrorState屬性似乎是說Added,並且還有一個錯誤對象,但它只是具有相同的文本,並且沒有真正的額外信息。

有沒有一種方法可以獲得有關實際錯誤的更好信息,例如如果這是主鍵違規,或以上方案中的其他情況?

在此先感謝!

回答

0

一種選擇是將您的數據批量插入空的臨時表,然後運行將臨時表中的數據合併到實際表中的存儲過程。如果沒有問題,您還可以調整您的查詢以排除重複項。

我也建議你使用SqlBulkCopy進行批量操作。根據我的經驗,SqlBulkCopy是將.NET中的數據批量加載到SQL Server的最快方法。還有很多有用的屬性可以設置。

https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy(v=vs.110).aspx