我开发了一个程序,该程序计算并在 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 打开和关闭连接,更不用说效率低下了。
至少你可以:
- 一次定义查询字符串、
SqlParameter
和SqlCommand
- 在循环中,设置参数值并调用
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/