从数据库表中写入文本文件的最快方法是什么?

4
我有一个数据分析应用程序,需要使用C#将数据库表导出为分隔符文本文件。由于应用程序的架构,必须将该数据传输到C#应用程序中。不能使用任何数据库导出功能。表的大小可能从几个列和几百行到超过一百万行的100多个列不等。
根据评论进一步澄清-- 我有一个Windows服务作为数据访问层,将从表示层获取导出请求。完成导出后,服务将需要将导出传回表示层,这可以是WPF应用程序或Silverlight应用程序,作为流对象。然后用户将获得保存或打开导出的选项。如何以最快的方式实现呢?谢谢。

那么,你无法从C#调用SSIS包吗? - John Saunders
现在是SQL,但以后会添加不同的关系型数据库管理系统。 - Dan R.
@John Saunders - 应用程序可能需要穿过防火墙才能访问数据库,因此在不进行重大架构更改的情况下,目前无法使用SSIS。 - Dan R.
你认为SSIS和防火墙之间有什么交互作用?无论是C#代码还是SSIS连接字符串,只要能够穿过防火墙的,都可以实现。 - John Saunders
@John Saunders - 或许我没有理解你的建议。我有一个作为数据访问层的Windows服务,将会接收导出请求。然后该服务需要将导出传递给呈现层,这可能是WPF应用程序或Silverlight应用程序。通过数据访问层,SSIS如何将数据传递到呈现层呢? - Dan R.
@Dan:数据导出后应该发生什么?UI层在数据导出后是否需要执行某些处理?您应该更新您的问题以使其更加详细。您的问题中甚至没有提到UI。 - John Saunders
7个回答

7

首先,如果不必使用C#,则SQL管理控制台可以完成此任务。

为了实现最佳性能,我建议使用消费者-生产者2线程概念:

  • 一个线程将是读取器,负责从数据库中读取项目 - 在这种情况下,我强烈推荐使用IReader来读取值,并将它们放在并发队列中。
  • 另一个将是写入器,只需使用fileStream从队列中写入数据。

您还可以通过分页方式读取信息来实现更高的性能。也就是说,如果您知道将有100000条记录,请将其分成1000个块,让读取器从数据库中读取这些块并将它们放入队列中。

虽然后一种解决方案更加复杂,但它将允许您以最佳方式利用CPU并避免延迟。


@MindFold - 谢谢。那么将数据写入流对象/文本文件的最有效方法是什么? - Dan R.
@Dan:只需使用连接到StreamReaderFileStream即可。 - John Saunders

3

谢谢,但由于架构的原因,我必须将数据带入一个C#应用程序中。 - Dan R.
如果必要的话,您可以将bcp封装并将其作为子进程执行。 - ConcernedOfTunbridgeWells

2
如果你使用的是SQL Server 2008(或者可能是2005),你可以右键单击数据库选择“任务->导出数据”。选择输入数据库,并选择“平面文件目标”作为输出。指定文件名,指定双引号为文本限定符,点击“下一步”几次即可完成。甚至可以将该任务保存为可再运行的SSIS包。
使用这种方式会在内部使用SSIS。它具有非常高的性能,因为它在管道中使用多个线程。

1

@Josh - 感谢你向我指出那个类。虽然我现在用不上它,但以后肯定会非常有帮助。 - Dan R.
我不确定,但我看到一些参考资料说它可以输出文本。 - Josh

0

如果你真正需要使用C#,最快的方式是使用ADO.NET的DataReader,它是只读且仅向前的,可能非常适合你。但要小心空字段,它处理得不是很好,如果你需要处理它们,也许其他ADO.NET资源对你更有趣。


0

如果您只需要快速查询数据,可以在一个或多个线程中使用“Firehose”游标,并直接从数据库中读取。


0

var sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["connstr"].ToString());
var sqlDataAdapter = new SqlDataAdapter("select * from tnm_story_status", sqlConnection); sqlConnection.Open();
var dataSet = new DataSet();
sqlDataAdapter.Fill(dataSet); sqlConnection.Close();
var dataTable = dataSet.Tables[0];
var streamWriter = new StreamWriter(@"C:\db.txt", false);
var sb = new StringBuilder();
for (var col = 0; col < dataTable.Columns.Count; col++)
{
if (sb.ToString() != "") sb.Append(",");
sb.Append(dataTable.Columns[col].ColumnName);
}
streamWriter.WriteLine(sb.ToString());
sb.Remove(0, sb.ToString().Length);
for (var row = 0; row < dataTable.Rows.Count; row++ )
{
for (var col = 0; col < dataTable.Columns.Count; col++)
{
if (sb.ToString() != "") sb.Append(",");
sb.Append(dataTable.Rows[row][col].ToString());
}
streamWriter.WriteLine(sb.ToString());
sb.Remove(0, sb.ToString().Length);
}
streamWriter.Close();


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