c# - 如何使用 C# 代码将大量数据插入 SQL Server 2008?

标签 c# sql-server sql-server-2008

我开发了一个程序,该程序计算并在 SQL Server 2008 的循环中插入大约 4800 行。但是在插入 200 多行后,它每次都会卡住并且不会插入其余行。

现在我正在用循环内的插入命令编写一个文本文件,而不是插入到数据库中。如果我尝试从文本日志中复制整个 4800 条插入命令并将其粘贴到 SQL Server 的查询编辑器中,那么它会在 1 分钟内全部插入。我想获得有关如何解决此问题的建议?我将不胜感激任何建议或帮助。

这是我现在正在尝试的代码示例:

 strSQL = "Insert into performance Values (@Rptdate,@CP_Name, @Shortcode, @Keyword, @MO_Count, @MO_Revenue,";
 strSQL = strSQL + "@PMT_Sent_Count, @MT_Revenue, @ZMT_Sent_Count, @Infra_Revenue, @Total_MT, @UM_rev_Share, @CP_Rev_Share, ";
 strSQL = strSQL + "@MCP_Rev_Share, @UM_Total_Revenue, @CP_Revenue)";

 try
 {
     db.openconn("MOMT_Report", "Report");
     cmd = new SqlCommand(strSQL, db.cn);

     cmd.Parameters.AddWithValue("@Rptdate", Rptdate);
     cmd.Parameters.AddWithValue("@Name", Name);
     cmd.Parameters.AddWithValue("@Shortcode", Shortcode);
     cmd.Parameters.AddWithValue("@Keyword", Keyword);
     cmd.Parameters.AddWithValue("@MO_Count", MO_Count);
     cmd.Parameters.AddWithValue("@MO_Revenue", MO_Revenue);
     cmd.Parameters.AddWithValue("@PMT_Sent_Count", PMT_Sent_Count);
     cmd.Parameters.AddWithValue("@MT_Revenue", MT_Revenue);
     cmd.Parameters.AddWithValue("@ZMT_Sent_Count", ZMT_Sent_Count);
     cmd.Parameters.AddWithValue("@Infra_Revenue", Infra_Revenue);
     cmd.Parameters.AddWithValue("@Total_MT", Total_MT);
     cmd.Parameters.AddWithValue("@rev_Share", rev_Share);
     cmd.Parameters.AddWithValue("@Rev_Share", Rev_Share);
     cmd.Parameters.AddWithValue("@MCP_Rev_Share", MCP_Rev_Share);
     cmd.Parameters.AddWithValue("@Total_Revenue", Total_Revenue);
     cmd.Parameters.AddWithValue("@Revenue", Revenue);

     cmd.CommandTimeout = 0;
     cmd.ExecuteNonQuery();
 }

最佳答案

在粘贴到问题中的 try block 之后的某处是否有 db.closeconn();?如果不是那么这是一个大问题(即保持打开连接而不是关闭它们,这可以解释为什么它在打开 200 多个连接后卡住)。如果有一个关闭连接方法被调用,那就太好了,但仍然不需要每次 INSERT 打开和关闭连接,更不用说效率低下了。

至少你可以:

  • 一次定义查询字符串、SqlParameterSqlCommand
  • 在循环中,设置参数值并调用ExecuteNonQuery();
  • (无论如何也最好不要使用 AddWithValue())

例子:

// this should be in a try block

strSQL = "INSERT...";
db.openconn("MOMT_Report", "Report");
cmd = new SqlCommand(strSQL, db.cn);

SqlParameter _Rptdate = new SqlParameter("@Rptdate", DbType.Int);
cmd.Parameters.Add(_Rptdate);

...{repeat for remaining params}...

// optional begin transaction

for / while loop
{
  _Rptdate.Value = Rptdate;
  // set other param values
  cmd.ExecuteNonQuery();
}

// if optional transaction was started, do commit

db.closeconn(); // this should be in a finally block

但是,插入此数据的最快和最干净的方法是使用 SQL Server 2008 中引入的表值参数 (TVP)。您需要创建一个用户定义的表类型(一次)来定义结构,然后您可以像当前那样在临时插入中使用它,或者传递给存储过程。但是这样你就不需要导出到一个文件来导入。不需要这些额外的步骤。

我没有复制/粘贴一个大的代码块,而是在下面的三个链接中标注了我发布的代码来执行此操作。前两个链接是完成此操作的完整代码(SQL 和 C#)。每个都是主题的细微变化(这显示了使用 TVP 的灵 active )。第三个是另一个变体,但不是完整的代码,因为它只是显示了与前两个中的一个的不同之处,以适应特定情况。但在所有 3 种情况下,数据都从应用流式传输到 SQL Server。没有创建任何额外的集合或外部文件;您使用当前拥有的内容,一次只需要复制一行的值即可发送。在 SQL Server 端,这一切都是作为填充的表变量来实现的。这比将内存中已有的数据转换为文件(需要时间和磁盘空间)或 XML(需要 cpu 和内存)或 DataTable(对于 SqlBulkCopy;需要 cpu)要高效得多和内存)或其他东西,仅依赖外部因素,例如文件系统(文件需要清理,对吗?)或需要解析 XML。

关于c# - 如何使用 C# 代码将大量数据插入 SQL Server 2008?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27371293/

相关文章:

c# - Luca Bolognese 的 "LINQ to SQL Overview"视频在哪里?

c# - 向 Spring.Net 中的递归方法注入(inject)建议?

java - 当 SQL 字符串获取 'SYSDATE' 作为字符串参数传递时,Spring Data Access 异常

sql-server - 如何将存储过程转换为 View ?

sql - 如何在 SQL Server 中通过 GROUP BY 使用 SUM?

c# - 推送开始调试后 VS 2013 停止工作

sql - T-SQL : can I use a variable as a database reference

c# - 自 SQL 2008 升级以来,SqlDataReader.HasRows 返回 false

c# - 我可以使用 Microsoft Sync Framework 将本地 ms access (mdb) 数据库与 SQL Server 同步吗?

C# Windows 窗体应用程序无法从基于 Linux 的服务器正确读取文件