批量更新SQL server的C#代码
我们有一个C代码,它将根据结构中的标志更新SQL server数据库表批量更新SQL server的C#代码,c#,.net,sql-server,c#-4.0,generics,C#,.net,Sql Server,C# 4.0,Generics,我们有一个C代码,它将根据结构中的标志更新SQL server数据库表 public struct stSRK { public string Sno; public string SClaimID; public bool SType; public string SText; } 结构中的数据一次最多可以访问5000-10000条记录。目前,我们正在使用以下C#代码更新数据库,它根据结构调用数据库的次数为“n”。有一种替代方法可以帮助您使用相同的结构进行
public struct stSRK
{
public string Sno;
public string SClaimID;
public bool SType;
public string SText;
}
结构中的数据一次最多可以访问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;
}
public int UpdateClaims(列表,字符串strClaimType)
{
尝试
{
int-iCount=0;
对于(int i=0;i<\u lt.Count;i++)
{
if(_lt[i].sType==true)
{
如果(_lt[i].SText=='A')
{
iCount+=Convert.ToInt16(SQL.ExecuteSQL(“更新表集ClaimType='”+strcaimtype+”,其中
(Sno=“+”lt[i].Sno+“”和ClaimID=“+”lt[i].SClaimID+”));
}
其他的
{
iCount+=Convert.ToInt16(SQL.ExecuteSQL(“更新表集ClaimType='”+strcaimtype+”,其中
(Sno=“+”lt[i].Sno+“”和ClaimID=“+”lt[i].SClaimID+”));
}
}
其他的
{
如果(_lt[i].SText=='B')
{
iCount+=Convert.ToInt16(SQL.ExecuteSQL(“更新表集ClaimType='”+strcaimtype+”,其中
(Sno=“+”lt[i].Sno+“”和ClaimID=“+”lt[i].SClaimID+”));
}
其他的
{
iCount+=Convert.ToInt16(SQL.ExecuteSQL(“更新表集ClaimType='”+strcaimtype+”,其中
(Sno=“+”lt[i].Sno+“”和ClaimID=“+”lt[i].SClaimID+”));
}
}
返回i计数;
}
捕获(例外e)
{
抛出e.消息;
}
尝试使用linq查询进行批量更新。这将提高应用程序的性能
您可以在此处获得有关批量更新linq查询的帮助:
希望这对您有所帮助。您的查询似乎对所有情况都是一样的 你不能重写你的代码,只生成一个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;
}
}
public int UpdateClaims(列表,字符串strClaimType)
{
尝试
{
string allSno=string.Join(“,”,_lt.Select(l=>l.Sno.ToString()).ToArray());
string allClaimID=string.Join(“,”,_lt.Select(l=>l.SClaimID.ToString()).ToArray());
//警告:非生产代码,有注入危险!
返回Convert.ToInt16(SQL.ExecuteSQL(“更新表集ClaimType='”+strcaimtype+@'),其中
(Sno IN(“+allSno+”)和ClaimID IN(“+allClaimID+”);
捕获(例外e)
{
//这不是一个好主意,因为这样你就失去了所有内在的例外
//有关异常的信息。您可能只想删除
//如果您只是重新显示异常,那么try-catch-allall将一起运行。
抛出e.消息;
}
}
我的代码:
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();
}
DataTable tblDetails=新数据表(“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 for(int j=1;j不!Linq较慢(有时非常慢)批量操作比ADO.Net快。@EricJ.是吗?我认为linq更快。我还使用linq进行25000到30000条记录的插入、更新和删除。我观察到,它比ADO每秒操作20条记录更快。NET@Freelancer是的,对SQL数据的批量操作可以比等效的Linq快得多一条记录一条记录,其中一个批量操作可以在一个操作中插入/更新数千条记录。@自由职业者:您是指Linq到SQL还是Linq到实体(EF)?我没有使用Linq to SQL,但在我的用例中Linq to Entities的速度要慢得多。Google entity framework速度慢,你会看到很多关于这个问题的帖子。@EricJ.:EF在几乎所有情况下都慢。请注意:这种方法不能很好地扩展到更大的更新—理想情况下应该是一种混合方法,即批量处理1000条记录(或对您正在处理的记录类型/环境有意义的任何内容)。如果您尝试使用200000条记录执行上述操作,SQL server可能会在查询解析时严重阻塞。此外,您建议的where子句中可能存在逻辑缺陷:如果我要删除Sno=1和ClaimID=2
的记录,并且我要删除Sno=2和ClaimID=1
的另一条记录,我也会意外地被删除g记录了Sno=1和ClaimID=1
或Sno=2和ClaimID=2
的位置。谢谢Tao,你是对的,我应该在我的回答中提到这一点。我跳到了一个可能错误的假设,即它们总是唯一的。这取决于OP将其放到上下文中,因为我不知道Sno是什么意思。SQL注入已经写得满天飞了虽然这只是对OP代码的重构,但我真的建议您自己的答案将查询参数化。答案有一种被其他人用作福音的方式。