导出数据库表时将字符串写入文件
本文关键字:字符串 文件 数据库 | 更新日期: 2023-09-27 18:28:32
我有一个表,它有一个名为ACTION_TYPE的字段。它的潜在值为"ADD"、"Change"、"DELETE"answers"-"。我想导出ACTION_TYPE值不是"-"的行。我成功地将表行以正确的格式导出到文件中,但是标题无法工作/正在写入。
基本上,我想要的是根据文件中的类型来分隔条目。例如
ADD
00 00 56 55
00 00 59 42
00 00 36 45
CHANGE
00 00 96 25
DELETE
00 00 76 75
00 00 38 95
到目前为止,我甚至没有成功地将其用于ADD。此外,当我使用这三种类型中的一种时,有没有比为每种类型(ADD、CHANGE、DELETE)克隆流程更好的方法?
using (StreamWriter writer =
new StreamWriter("C:''BillingExport''EXPORTS''EFTHLDAY.TABLE.TYPE08.TRANSACTIONS.txt"))
{
writer.Write("ADD");
}
string selectCommandText42 = "SELECT * FROM HOLIDAY_DATE_TABLE WHERE ACTION_TYPE = 'ADD '";
using (SqlDataAdapter adapter42 = new SqlDataAdapter(selectCommandText42, connection))
{
using (DataTable table42 = new DataTable("HOLIDAY_DATE_TABLE"))
{
adapter42.Fill(table42);
System.Text.StringBuilder commaDelimitedText = new System.Text.StringBuilder();
//commaDelimitedText.AppendLine("col1,col2,col3"); // optional if you want column names in first row
foreach (DataRow row in table42.Rows)
{
string value = string.Format("{0} {0} {1} {2}", row[1], row[2], row[3]); // how you format is up to you (spaces, tabs, delimiter, etc)
commaDelimitedText.AppendLine(value);
}
System.IO.File.WriteAllText("C:''BillingExport''EXPORTS''EFTHLDAY.TABLE.TYPE08.TRANSACTIONS.txt", commaDelimitedText.ToString());
}
}
更新:实现下面的一些建议,我现在有了以下代码
string selectCommandText42 = "SELECT * FROM HOLIDAY_DATE_TABLE WHERE ACTION_TYPE != '-'";
using (SqlDataAdapter adapter42 = new SqlDataAdapter(selectCommandText42, connection))
{
using (DataTable table42 = new DataTable("HOLIDAY_DATE_TABLE"))
{
adapter42.Fill(table42);
System.Text.StringBuilder commaDelimitedText = new System.Text.StringBuilder();
//commaDelimitedText.AppendLine("col1,col2,col3"); // optional if you want column names in first row
foreach (DataRow row in table42.Rows)
{
string rowtype = row[4].ToString();
using (StreamWriter writer =
new StreamWriter("C:''BillingExport''EXPORTS''EFTHLDAY.TABLE.TYPE08.TRANSACTIONS.txt")){
writer.WriteLine(rowtype);
}
string value = string.Format("{0} {0} {1} {2}", row[1], row[2], row[3]); // how you format is up to you (spaces, tabs, delimiter, etc)
commaDelimitedText.AppendLine(value);
}
System.IO.File.AppendAllText("C:''BillingExport''EXPORTS''EFTHLDAY.TABLE.TYPE08.TRANSACTIONS.txt", commaDelimitedText.ToString());
}
}
这提供了以下输出
ADD
00 00 96 25
00 00 76 75
00 00 38 95
00 00 56 55
00 00 59 42
00 00 36 45
它似乎没有应用CHANGE或DELETE标头,也没有按适当的顺序列出条目(ADD条目现在位于创建的文件的底部)。
是的,有一种更好的方法不需要:
- 复制代码
- 将整个结果集拉入存储器(即
DataTable
) - 再次以
StringBuilder
的形式复制存储器中的整个结果集
一般概念是:
-
在单个SELECT中查询所需的所有数据。你可以通过匹配的需求来做到这一点
ACTION_TYPE值不是"-"
通过使用
WHERE ACTION_TYPE <> '-'
的WHERE子句 -
对结果进行排序,以便按照"添加"、"更改"answers"删除"的预定顺序获得结果。您可以通过添加一个简单的
ORDER BY ACTION_TYPE ASC
来实现这一点 -
循环通过
SqlDataReader.Read()
并执行"控制中断"(我相信这个概念有各种名称)以应用新的标题,如果ACTION_TYPE
的当前行的值与前一行不同。 -
在处理文件时,将每一行都写入文件。使用StreamWriter.WriteLine(String,Object,Object,Object)输出行,同时对其进行格式化。
请注意:
- 您可能需要调整
_Reader.GetString
调用的索引值,因为我对架构没有深入了解,也不确定哪一列是ACTION_TYPE
- 建议按名称显式选择字段,而不是使用
SELECT *
- 通过在字符串前加
@
,它不会转换转义序列,因此在文件路径中不需要双反斜杠:)
代码:
using System.IO;
using System.Data.SqlClient;
string _CurrentActionType = "";
SqlConnection _Connection = new SqlConnection("connection string");
SqlCommand _Command = new SqlCommand(
@"SELECT *
FROM HOLIDAY_DATE_TABLE
WHERE ACTION_TYPE <> '-'
ORDER BY ACTION_TYPE ASC;",
_Connection
);
SqlDataReader _Reader = null;
try
{
_Connection.Open();
_Reader = _Command.ExecuteReader();
if (_Reader.HasRows())
{
using (StreamWriter writer =
new StreamWriter(
@"C:'BillingExport'EXPORTS'EFTHLDAY.TABLE.TYPE08.TRANSACTIONS.txt"))
{
while (_Reader.Read())
{
// assuming [ACTION_TYPE] field is 5th column; adjust accordingly
if (_Reader.GetString(4) != _CurrentActionType)
{
_CurrentActionType = _Reader.GetString(4);
writer.WriteLine(_CurrentActionType);
}
writer.WriteLine(
"{0} {0} {1} {2}",
_Reader.GetInt32(1), _Reader.GetInt32(2), _Reader.GetInt32(3));
}
}
}
}
finally
{
_Reader.Close();
_Connection.Close();
}
每次在循环中调用File.WriteAllText
时,都会覆盖以前的更改:
创建一个新文件,将内容写入该文件,然后关闭该文件。
如果目标文件已经存在,它将被覆盖。
请改用File.AppendAllText
,因为它将而不会覆盖您的文件:
打开一个文件,将指定的字符串附加到该文件,然后关闭该文件。
修改代码:
File.AppendAllText(@"C:'BillingExport'EXPORTS'EFTHLDAY.TABLE.TYPE08.TRANSACTIONS.txt",
commaDelimitedText.ToString());
另一种方法是使用数据集。sql命令将类似于
var sqlQuery = "SELECT * FROM HOLIDAY_DATE_TABLE WHERE ACTION_TYPE = 'ADD';
SELECT * FROM HOLIDAY_DATE_TABLE WHERE ACTION_TYPE = 'CHANGE';
SELECT * FROM HOLIDAY_DATE_TABLE WHERE ACTION_TYPE = 'DELETE';"
然后将其加载到DataSet并通过Tables属性进行引用
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/5e594f9e-98b2-4a47-a87f-a5151e0c7828/loading-multiple-tables-within-dataset-in-single-call-c
您可以通过ACTION_TYPE:更改查询顺序
"SELECT * FROM HOLIDAY_DATE_TABLE WHERE ACTION_TYPE IN ('ADD ', 'DELETE ', 'Change ') ORDER BY ACTION_TYPE ASC"
然后,在LOOP:中应用此逻辑
1) 保存你遇到的第一种类型,并写下来:
string rowtype = table42.Rows[0].Item("ACTION_TYPE");
writer.Write(rowtype);
2) 当类型发生变化时进行检查,只有在发生变化时才写入:
foreach (DataRow row in table42.Rows)
{
if (row.Item("ACTION_TYPE").ToString() != rowtype)
{
commaDelimitedText.AppendLine(rowtype);
}
string value = string.Format("{0} {0} {1} {2}", row[1], row[2], row[3]); // how you format is up to you (spaces, tabs, delimiter, etc)
commaDelimitedText.AppendLine(value);
}
3)
要编写文件,请使用file.AppendAllText:
File.AppendAllText(_YOURFILEHERE_, commaDelimitedText.ToString());
我没有尝试就写了它,它可能会工作