批量发送数据到存储过程

时间:2010-07-13 19:04:08

标签: asp.net sql-server xml vb.net stored-procedures

我正在使用Microsoft .NET Framework 3.5使用VB.NET创建Web服务。我在SQL Server 2008中使用存储过程,以便SQL可以插入我传递的所有数据。

问题是,在其中一个服务器中,我需要传递大约10,000条记录,并且运行存储过程10,000次效率不高。

我读到有一种方法可以将包含所有数据的XML文件传递给存储过程,但我不确定这是否是最有效的方法。此外,我无法使代码工作,我不知道是否必须将XML作为字符串传递。

我正在寻求一种方法的帮助,在这种方法中,我可以将大量记录传递给存储过程一次,然后存储过程的同一实例可以处理循环中的所有记录

提前谢谢大家。

5 个答案:

答案 0 :(得分:5)

SqlBulkCopy in .NET,但我希望你能看一下table-valued parameter.

答案 1 :(得分:3)

您可以将文本语句传递给数据库。它可以非常有效。

而不是创建SqlCommand CommandType.StoredProcedure并获取单个存储过程名称和参数集 - 如果您为每条记录往返数据库,那么您怀疑它将表现不佳 - 您可以创建一个SqlCommand CommandType.Text,然后构造一个包含多个SQL语句的文本批处理(这将是您的存储过程的调用。)用分号分隔每个语句。

文本批处理的另一个优点是您的存储过程可以保持简单,并且一次只处理一条记录。

但是,要小心:您需要确保正确引用/转义参数,因为创建纯文本批处理而不是使用CommandType.StoredProcedure(带参数)可以打开SQL - 注射型漏洞。

答案 2 :(得分:2)

我使用的方法是将CDATA块(在我的情况下以管道分隔)中的数据传递给Web服务,然后执行:

  1. 将CDATA块保存到Web服务器上的临时文件
  2. 然后使用命令行实用程序bcp.exe将数据批量加载到临时表
  3. 然后调用设置的存储过程来处理登台表中的所有记录
  4. 比为每条记录调用proc更快,压力更小。

    编辑:现在我已经阅读了有关SqlBulkCopy的内容,我会这样做:

    1. 将CDATA块数据写入DataTable
    2. 使用SqlBulkCopy将数据放入临时表: - )
    3. 然后调用设置的存储过程来处理登台表中的所有记录

答案 3 :(得分:1)

答案 4 :(得分:0)

在我使用SQL Server 2000之前,我已经使用OPENXML(通过@EJB建议)在我的代码中构造XML字符串,将其传递到{{1中的存储过程参数,使用text将XML解析为关系结构并从那里继续进行,例如

VB

OPENXML

SQL

Dim xmlStringBuilder As System.Text.StringBuilder

xmlStringBuilder = New System.Text.StringBuilder
xmlStringBuilder.Append("<objects>"
For Each object In Collection
    'I'm not suggesting this is the best way to build XML, it is however reliable!
    xmlStringBuilder.Append("<object id='" & object.id.ToString & "'></object>"
Next
xmlStringBuilder.Append("</objects>"

Dim xmlStoredProcCommand As SqlCommand
Dim xmlParameter As SqlParameter
xmlStoredProcCommand = New SqlCommand(connection)
xmlStoredProcCommand.CommandType = CommandType.StoredProcedure
xmlStoredProcCommand.CommandText = "xmlStoredProc"
xmlParameter = New SqlParameter("@xmlParameter",SqlDbType.NText)
xmlParameter.Value = xmlStringBuilder.ToString
xmlStoredProcCommand.Parameters.Add(xmlParameter)
xmlStoredProcCommand.ExecuteNonQuery

从那里你可以使用@objects表变量的内容来完成你的工作。