[英]c# Build very large text file from SQL query
我从SQL数据库中获取了100多个表,并将所有数据写入1个文件。 在SQL中,我运行了一个复杂的查询来将表格格式化为一个视图。 在VS中,我连接到SQL并从视图中选择*并使用String Builder构建文件。
如果我只抓住5%的数据并且因为内存异常而崩溃,如果我试图抓住100%,这是有效的。 该视图有1000万条记录。 我在寻求建议。 谢谢。
string cs4 = ConfigurationManager.ConnectionStrings["example"].ConnectionString;
StringBuilder sb4 = new StringBuilder();
using (SqlConnection con4 = new SqlConnection(cs4))
{
string strTQuery = @"SELECT * FROM [dbo].[view]";
SqlDataAdapter da4 = new SqlDataAdapter(strTQuery, con4);
DataSet ds4 = new DataSet();
da4.Fill(ds4);
ds4.Tables[0].TableName = "Example";
foreach (DataRow exDR in ds4.Tables["Example"].Rows)
{
sb4.Append(exDR["A"].ToString() + strDelimiter);
sb4.Append(exDR["B"].ToString() + strDelimiter);
sb4.Append(exDR["C"].ToString() + strDelimiter);
sb4.Append(exDR["D"].ToString());
sb4.Append("\r\n");
}
}
StreamWriter file4 = new StreamWriter(@"\\Desktop" + todaysDate + ".csv");
file4.WriteLine(sb4.ToString());
file4.Close();
正如D Stanley
所提到的,你需要在阅读的同时进行编写,这样一切都可以直接进入磁盘并且不会首先进入内存然后进入磁盘。 像这样的东西会起作用。
string cs4 = ConfigurationManager.ConnectionStrings["example"].ConnectionString;
using (SqlConnection con4 = new SqlConnection(cs4))
using(StreamWriter file4 = new StreamWriter(@"\\Desktop" + todaysDate + ".csv"))
{
string strTQuery = @"SELECT A, B, C, D FROM [dbo].[view]";
var command = new SqlCommand(strTQuery, con4);
con4.Open();
var reader = command.ExecuteReader();
while(reader.Read())
{
file4.Write(reader.GetString(0) + strDelimiter);
file4.Write(reader.GetString(1) + strDelimiter);
file4.Write(reader.GetString(2) + strDelimiter);
file4.Write(reader.GetString(3));
file4.Write("\r\n");
}
}
您还应该使用SqlDataReader而不是DataSet,因为这是一个正向移动指针,并在每次迭代时检索结果。
您正试图将整个文件存储在运行时内存中,这就是您收到内存错误的原因。 尝试保存文件块并修改文件。
尝试
string cs4 = ConfigurationManager.ConnectionStrings["example"].ConnectionString;
StringBuilder sb4 = new StringBuilder();
using (SqlConnection con4 = new SqlConnection(cs4))
{
StreamWriter file4 = new StreamWriter(@"\\Desktop" + todaysDate + ".csv", true);
string strTQuery = @"SELECT * FROM [dbo].[view]";
SqlDataAdapter da4 = new SqlDataAdapter(strTQuery, con4);
DataSet ds4 = new DataSet();
da4.Fill(ds4);
ds4.Tables[0].TableName = "Example";
foreach (DataRow exDR in ds4.Tables["Example"].Rows)
{
sb4 = new StringBuilder();
sb4.Append(exDR["A"].ToString() + strDelimiter);
sb4.Append(exDR["B"].ToString() + strDelimiter);
sb4.Append(exDR["C"].ToString() + strDelimiter);
sb4.Append(exDR["D"].ToString());
sb4.Append("\r\n");
file4.WriteLine(sb4.ToString());
}
file4.Close();
}
问题出在这一行:
file4.WriteLine(sb4.ToString());
原因是CLR中没有对象可以大于2GB。 在这种情况下你的字符串异常大,甚至不需要这样的行为(ToString我的意思)。 要避免此问题,请使用FileStream在收到数据时写入数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.