如何将数据流流入sqlserver?

时间:2011-08-10 12:59:53

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

我需要从一个数据库复制大型结果集并将其保存到另一个数据库。

存储过程用于获取和存储,因为在保存期间涉及一些逻辑。

我正试图找到一个高效的解决方案,我无法将整个数据集保存在内存中,我希望尽量减少往返次数。

使用

从源表中读取数据
var reader = fetchCommand.ExecuteReader();
while (reader.Read()){...}

有没有办法将这些数据插入到另一个sqlCommand,而无需将整个数据集加载到DataTable中,而且还没有一行插入一行?

Sqlserver是源数据库和目标数据库上的MS SQL Server 2008。数据库位于不同的服务器上。无法使用SSIS或链接服务器。

修改 看来可以使用table-valued paramaters将行流式传输到存储过程中。也将研究这种方法。

更新 是的,可以将数据从command.ExecuteReader流式传输到另一个命令,如下所示:

var reader = selectCommand.ExecuteReader();
insertCommand.Parameters.Add(
    new SqlParameter("@data", reader)
        {SqlDbType = SqlDbType.Structured}
    );

insertCommand.ExecuteNonQuery();

其中insertCommand是具有表值参数@data的存储过程。

2 个答案:

答案 0 :(得分:5)

您需要SqlBulkCopy。您可以像这样使用它:

using (var reader = fetchCommand.ExecuteReader())
using (var bulkCopy = new SqlBulkCopy(myOtherDatabaseConnection))
{
  bulkCopy.DestinationTableName = "...";
  bulkCopy.ColumnMappings = ...
  bulkCopy.WriteToServer(reader);
}

还有一个属性可以设置批量大小。像1000行这样的东西可能会让你在内存使用和速度之间做出最佳平衡。

虽然这不允许您将其传递到存储过程,但最好的方法可能是将数据复制到临时表,然后在服务器上运行批量更新命令以将数据复制到其最终位置。这通常比为每行执行大量单独的语句更快。

答案 1 :(得分:3)

您可以将SqlBulkCopy与数据阅读器一起使用,大致您要求的内容(非缓冲等) - 但是, 不会 调用要插入的存储过程。如果您需要,可以使用SqlBulkCopy将数据推送到第二个表(相同的结构),然后在数据库服务器上 ,遍历调用本地sproc的行。这样,延迟等不再是一个问题(因为循环都在数据库服务器上)。