2010-02-24 28 views
9

執行批處理更新我想更新多個行像以下如何在SQL通過C#代碼

update mytable set s_id = {0} where id = {1} 

(這裏s_id基於一些複雜的邏輯被評估)。
由於性能原因,更新應該分批進行。有沒有辦法批量更新語句並通過單個執行語句執行批處理?我知道在JAVA中我們可以通過JDBC來做到這一點。在C#中有類似的方法嗎?

在此先感謝

回答

18

是的,你可以使用SqlDataAdapter

的SqlDataAdapter的具有InsertCommandUpdateCommand屬性,讓你可以指定的SqlCommand使用插入新行到數據庫和的SqlCommand分別以更新數據庫中的行。

然後,您可以將DataTable傳遞給dataadapter的Update方法,並且它會將語句批量添加到服務器 - 對於DataTable中作爲新行的行,它將執行INSERT命令,對於它執行的修改行UPDATE命令。

您可以使用UpdateBatchSize屬性定義批量大小。

這種方法允許你處理大量的數據,並允許你以不同的方式很好地處理錯誤,例如,如果遇到特定更新時發生錯誤,你可以告訴它不要拋出異常,但要攜帶通過設置ContinueUpdateOnError屬性與其餘的更新進行通信。

0

創建一組的更新(與ID的填寫),由分號在一個字符串將它們分開,將得到的字符串到一個SqlCommand的CommandText屬性,然後調用的ExecuteNonQuery()。

2

使用StringBuilder(System.Text.StringBuilder)來構建你的SQL,如:

StringBuilder sql = new StringBuilder(); 
int batchSize = 10; 
int currentBatchCount = 0; 
SqlCommand cmd = null; // The SqlCommand object to use for executing the sql. 
for(int i = 0; i < numberOfUpdatesToMake; i++) 
{ 
    int sid = 0; // Set the s_id here 
    int id = 0; // Set id here 
    sql.AppendFormat("update mytable set s_id = {0} where id = {1}; ", sid, id); 

    currentBatchCount++; 
    if (currentBatchCount >= batchSize) 
    { 
    cmd.CommandText = sql.ToString(); 
    cmd.ExecuteNonQuery(); 
    sql = new StringBuilder(); 
    currentBatchCount = 0; 
    } 
} 
+3

很可能是因爲SQL注入攻擊可能與您的代碼相關 – GvS 2010-02-24 16:25:17

+1

如果它只是整數值 – 2011-10-24 13:01:23

+1

@GvS SQL注入在沒有不可信輸入時不相關時不適用。任何能夠改變'int id = 0'的人都可以輕鬆地改變整個查詢。 – Dan 2014-08-19 16:07:26

9

是的,你可以建立一個純文本SQL命令(參數出於安全考慮),像這樣:

SqlCommand command = new SqlCommand(); 
// Set connection, etc. 
for(int i=0; i< items.length; i++) { 
    command.CommandText += string.Format("update mytable set [email protected]_id{0} where id = @id{0};", i); 
    command.Parameters.Add("@s_id" + i, items[i].SId); 
    command.Parameters.Add("@id" + i, items[i].Id); 
} 
command.ExecuteNonQuery(); 
+0

我喜歡這種方法。我的目的比SqlDataAdapter更容易實現/調試。 – Dan 2014-08-19 20:05:46

+1

只是爲了提醒您僅限於2100個參數! – Arvand 2016-10-25 14:12:53

+0

@Arvand你如何解決這個問題? – Arvayne 2017-03-31 08:11:11