2013-03-11 44 views
1

我们有这个C#代码将根据结构中的标志更新SQL Server数据库表。C#代码批量更新SQL服务器

public struct stSRK 
{ 
    public string Sno; 
    public string SClaimID; 
    public bool SType; 
    public string SText; 
} 

中的数据结构可以在time.Currently去高达5000-10000记录,我们使用的是下面的C#代码更新数据库,它使基于该结构的数据库调用的“N”数字。将有助于有一个替代方案使用相同的结构进行批量更新。请参阅下面的方法

public int UpdateClaims(List<stSRK> _lt, string strClaimType) 
{ 
try 
{ 
    int iCount = 0; 
    for (int i = 0; i < _lt.Count; i++) 
     { 
      if (_lt[i].sType == true) 
      { 
       if (_lt[i].SText == 'A') 
       { 
       iCount += Convert.ToInt16(SQL.ExecuteSQL("UPDATE table SET ClaimType = '" + strClaimType + "' WHERE 
        (Sno = '" + _lt[i].Sno + "' AND ClaimID = '" + _lt[i].SClaimID + "')")); 
       } 
       else 
       { 
       iCount += Convert.ToInt16(SQL.ExecuteSQL("UPDATE table SET ClaimType = '" + strClaimType + "' WHERE 
        (Sno = '" + _lt[i].Sno + "' AND ClaimID = '" + _lt[i].SClaimID + "')")); 
       } 
      } 
      else 
      { 
       if (_lt[i].SText == 'B') 
       { 
       iCount += Convert.ToInt16(SQL.ExecuteSQL("UPDATE table SET ClaimType = '" + strClaimType + "' WHERE 
        (Sno = '" + _lt[i].Sno + "' AND ClaimID = '" + _lt[i].SClaimID + "')")); 
       } 
       else 
       { 
       iCount += Convert.ToInt16(SQL.ExecuteSQL("UPDATE table SET ClaimType = '" + strClaimType + "' WHERE 
        (Sno = '" + _lt[i].Sno + "' AND ClaimID = '" + _lt[i].SClaimID + "')")); 
       } 
      } 
     return iCount; 
     } 
catch (Exception e) 
{ 
    throw e.Message; 
} 

回答

1

您的查询似乎是相同的所有情况..

你不能重写你的代码来构建只有一个SQL语句?

事情是这样的:

public int UpdateClaims(List<stSRK> _lt, string strClaimType) 
{ 
    try 
    { 
     string allSno = String.Join(",", _lt.Select(l=> l.Sno.ToString()).ToArray()); 
     string allClaimID = String.Join(",", _lt.Select(l=> l.SClaimID.ToString()).ToArray()); 

     // Warning: NOT Production code, SQLInjection hazard! 
     return Convert.ToInt16(SQL.ExecuteSQL("UPDATE table SET ClaimType = '" + strClaimType + @"' WHERE 
         (Sno IN(" + allSno + ") AND ClaimID IN(" + allClaimID + "))")); 
    catch (Exception e) 
    { 
     //This is not a good idea, as this way you loose all innerException 
     // information about the exception. And you might just want to remove 
     // the try-catch alltogether if you just rethrow the exception. 
     throw e.Message; 
    } 
} 
+0

值得注意的是:这种方法不能很好地适应更大的更新 - 理想情况下应该是一种混合方法,在这种方法中,您可以批量处理1,000条记录(或者对于所处理的记录/环境类型有意义)。如果你用200,000条记录尝试上面的内容,SQL服务器可能会在查询分析中窒息。 – Tao 2013-09-18 12:10:46

+0

此外,在你提出的where子句中可能存在一个逻辑缺陷:如果我想删除一个'Sno = 1 AND ClaimID = 2'的记录,并且我想删除'Sno = 2 AND ClaimID = 1'的另一个记录, ,我也会意外删除'Sno = 1 AND ClaimID = 1'或'Sno = 2 AND ClaimID = 2'的记录。 – Tao 2013-09-18 12:12:28

+0

感谢陶,你说得很对,我应该在我的回答中提到这一点。我跳到了可能错误的假设,即他们总是独一无二的。由于我不知道Sno的含义,所以由OP来完成。 – Peter 2013-09-18 12:58:49

0

尝试使用linq查询进行批量更新。这将提高应用程序的性能。

你可以得到大规模更新用LINQ查询帮助在这里:

How to run a mass update/delete query in Linq?

http://msdn.microsoft.com/en-us/library/bb399339.aspx

希望这会帮助你。

+5

NO!对于批量操作,Linq比ADO.Net慢(有时非常慢)。 – 2013-03-11 05:05:01

+0

@EricJ。是吗?我认为linq更快。我也使用Linq为25000到30000记录插入,更新删除。我观察到,它使得操作速度比ADO.NET快20秒/秒 – Freelancer 2013-03-11 05:07:20

+0

@Freelancer对于SQL数据,** Bulk Operations **可以比等效的Linq快得多,速度更快。 Linq插入/更新按记录进行记录,批量操作可以在单个操作中插入/更新数千条记录。 – Corey 2013-03-11 06:15:22

1

我的代码:

DataTable tblDetails = new DataTable("tblPlanDetail"); 

     tblDetails.Columns.Add("row1").DataType = typeof(Int32); 
     tblDetails.Columns.Add("row2").DataType = typeof(DateTime); 
     tblDetails.Columns.Add("row3").DataType = typeof(String); ; 
     tblDetails.Columns.Add("row4").DataType = typeof(Int32); ; 


     for (int i = 0; i < table.Rows.Count; i++) 
     { 

      for (int j = 1; j <= DateTime.DaysInMonth(monthYear.Year, monthYear.Month); j++) 
      { 
       DataRow row = tblDetails.NewRow(); 

       DateTime DayOfMonth = new DateTime(monthYear.Year, monthYear.Month, j); 
       row["row1"] = idPlan; 
       row["row2"] = DayOfMonth; 
       row["row3"] = table.Rows[i][0]; 
       row["row4"] = Int32.Parse((string)table.Rows[i][j]); 

       tblDetails.Rows.Add(row); 
      } 
     } 

     try 
     { 

      SqlBulkCopy sqlbulk = new SqlBulkCopy(connection, SqlBulkCopyOptions.KeepIdentity, transaction); 
      sqlbulk.ColumnMappings.Add("row1", "row1"); 
      sqlbulk.ColumnMappings.Add("row2", "row2"); 
      sqlbulk.ColumnMappings.Add("row3", "row3"); 
      sqlbulk.ColumnMappings.Add("row4", "row4"); 

      sqlbulk.DestinationTableName = "tblPlanDescription"; 
      sqlbulk.BatchSize = 2; 
      sqlbulk.WriteToServer(tblDetails); 
      transaction.Commit(); 
     } 
     catch (Exception exp) 
     { 

      transaction.Rollback(); 
     } 
     finally 
     { 
      transaction.Dispose(); 
      connection.Close(); 
     } 

即批量插入。 您可以将其插入临时表中。 则可以执行SP,这将创造neccessary索引和服务器端更新neccesary数据

看看here