将大量数据行传递给存储过程

gan*_*any 8 c# xml

我正在通过C#阅读电子表格文件...我的电子表格有超过1000行.我需要将每行数据发送到存储过程以执行一些数据库端逻辑和更新记录.我需要一些帮助才能在一次往返中发送所有这1000行数据以节省时间.将所有这1000行数据分组的技术是什么?

Rya*_*sen 21

猜测您使用的是SQL Server 2008或更高版本,您有几个选择.所有这些选项都在新奥尔良的Tech-Ed 2010中进行了详细介绍,会议视频可在线获取.以下是所提供选项的摘要.

选项#1 - 批量插入(视频中没有真正覆盖)

如果您只需要将数据"转储"到表中,并且除了将数据放入数据库之外不需要对数据做很多事情,这是一个很好的选择.ADO.NET中也支持使用SqlBulkCopy对象.我还编写了一个可以在CodePlex找到轻量级包装器,以便更轻松地使用SQL Server和ADO.NET

选项#2 - 传递分隔列表

获取所有数据并构建一个大字符串并将整个字符串传递给存储过程.这是惊人的快,但带来了很多包袱.您必须具有拆分功能才能获取数据并获得使用SQL-CLR进行拆分所需的最佳性能,如果您不拥有数据库,则可以使用showstopper.

选项#3 - 传递为XML

这几乎与选项#2相同,因为您再次将一个巨大的字符串传递给一个参数.这也具有合理的性能,但也带有与Option#2相同但没有拆分功能的大部分行李,因为Sql Server知道如何解析XML.

选项#4 - 使用表值函数(SQL Server 2008)

此选项非常酷,可提供最佳性能.首先在SQL Server中创建一个类型为"Table"的值类型,然后创建一个存储过程,将该值类型作为参数.在C#中,您现在可以创建一个SqlCommand并添加一个类型为SqlDbType.Structured的参数.

cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Test.spTVP";
var p = cmd.Parameters.Add("@Values", SqlDbType.Structured);
p.TypeName = "Test.OrderTableType";
p.Value = dataTable;
cmd.Execute…;
Run Code Online (Sandbox Code Playgroud)

执行存储过程时,存储过程的表变量中提供了所有数据.它可以像任何其他表变量一样使用,因此移动数据非常简单.

选项#5 - 使用表值函数(SQL Server 2008)

还有一点工作然后选项#4,因为你必须设置一个迭代器,但是你得到了一些疯狂的性能,因为你不必在将它传递到存储过程之前加载客户端上的所有数据..NET运行时实际上将数据流式传输到数据库中,并且存储过程的实现是相同的.

class MyStreamingTvp : IEnumerable<SqlDataRecord> { …
}
…
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Test.spTVP";
var p = cmd.Parameters.Add("@Values", SqlDbType.Structured);
p.TypeName = "Test.OrderTableType";
p.Value = new MyStreamingTvp(…);
cmd.Execute…;
Run Code Online (Sandbox Code Playgroud)

所有这些选项都在我开头提到的视频中有很多细节和一点点幽默.这是今年Tech-Ed最喜欢的课程之一.