2010-02-24 66 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