导出数据库表时将字符串写入文件

本文关键字:字符串 文件 数据库 | 更新日期: 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条目现在位于创建的文件的底部)。

导出数据库表时将字符串写入文件

是的,有一种更好的方法不需要:

  1. 复制代码
  2. 将整个结果集拉入存储器(即DataTable
  3. 再次以StringBuilder的形式复制存储器中的整个结果集

一般概念是:

  1. 在单个SELECT中查询所需的所有数据。你可以通过匹配的需求来做到这一点

    ACTION_TYPE值不是"-"

    通过使用WHERE ACTION_TYPE <> '-' 的WHERE子句

  2. 对结果进行排序,以便按照"添加"、"更改"answers"删除"的预定顺序获得结果。您可以通过添加一个简单的ORDER BY ACTION_TYPE ASC 来实现这一点

  3. 循环通过SqlDataReader.Read()并执行"控制中断"(我相信这个概念有各种名称)以应用新的标题,如果ACTION_TYPE的当前行的值与前一行不同。

  4. 在处理文件时,将每一行都写入文件。使用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());

我没有尝试就写了它,它可能会工作