如何将数据行流到sqlserver中

本文关键字:sqlserver 数据 | 更新日期: 2023-09-27 18:05:11

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

存储过程既用于获取也用于存储,因为在保存过程中涉及到一些逻辑。

我试图找到一个有效的解决方案,我不可能在内存中保存整个数据集,我想最小化往返次数。

使用

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

是否有一种方法可以将此数据插入到另一个sqlCommand而不将整个数据集加载到DataTable,但也不插入行?

Sqlserver在源和目标数据库上都是MS SQL Server 2008。数据库位于不同的服务器上。使用SSIS或链接服务器不是一个选项。

编辑:

似乎可以使用表值参数将行流式传输到存储过程中。我们也会研究这个方法。

更新:是的,可以将数据从command.ExecuteReader流到另一个命令,像这样:

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

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

如何将数据行流到sqlserver中

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

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

还有一个属性用于设置批处理大小。像1000行这样的值可能会在内存使用和速度之间做出最好的权衡。

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

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