如何从Ado.Net高效地调用表值参数

7
我需要高效地从Ado.Net向SQL Server 2008提交数万个数字和日期。在SQL 2008之前,我将这些数字打包成图像,速度相当快。Erland Sommarskog很友好地在他的文章Arrays and Lists in SQL Server 2005中包含了我的一些代码。
由于现在我们可以使用TVPs,我尝试了它们。在客户端上,我运行以下代码:
        dataTable = new DataTable();
        dataTable.Columns.Add("Date", typeof(DateTime));
        dataTable.Columns.Add("Price", typeof(decimal));
        dataTable.Rows.Add(new object[] { someDate, somePrice });
            command.CommandText = "Writers.SavePrices";
            command.CommandType = CommandType.StoredProcedure;
            var param = command.Parameters.AddWithValue("@Prices", dataTable);
            param.SqlDbType = SqlDbType.Structured;

这段代码可以运行,但我认为它并不高效。我启动了Profiler,立即看到Ado.Net向服务器发送了以下极其低效的SQL语句:

DECLARE @Prices TABLE(...)
INSERT INTO @Prices(...)VALUES(...)
EXEC Writers.SavePrices @Prices=@Prices

作为结果,服务器上的大量网络带宽和CPU被浪费在发送、解析和编译上。是否有更有效的方法使用Ado.Net中的TVPs?

2
你知道SqlBulkCopy吗?它非常高效和灵活。这里有一个例子。 - Tim Schmelter
@Tim:当然,我可以使用SqlBulkCopy将数据导入到临时表中。但是,我无法找到一种方法让SqlBulkCopy和TVPs一起工作。 - A-K
我提到它作为TVP的替代方案。请参阅这里这里,了解有关SQLBulkCopy与TVP相比的更多有趣信息。 - Tim Schmelter
@Tim:你能把你的评论复制到答案中吗,这样我就可以接受它了吗?显然没有更好的方法。 - A-K
ADO.NET是否像这篇博客文章所描述的那样,发送成千上万个INSERT语句(每个TVP中的每一行都有一个INSERT)? - Nick Chammas
@NickChammas:这篇博客文章恰好告诉我Profiler正在告诉我的事情:每行一个INSERT。 - A-K
1个回答

2
你知道 SqlBulkCopy 吗?它非常高效且灵活。这里 有一个例子。
我提到它作为 TVP 的替代方案。查看 这里这里 获取更多关于 SQLBulkCopy 相对于 TVP 的有趣信息。
(评论内容复制)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接