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

时间:2014-10-31 13:26:08

标签: c# sql sql-server

我有一个名为ACTION_TYPE的表。它的潜在价值是" ADD","更改"," DELETE"和" - "。我想导出ACTION_TYPE值不是' t" - "的行。我已成功将正确格式的表格行导出到文件中,但标题不能正常工作/正在写入。

基本上我想要的是按条目中的类型分隔条目。例如

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条目现在位于创建文件的底部)。

4 个答案:

答案 0 :(得分:2)

是的,有一个很多更好的方式,不需要:

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

    一般概念是:

    1. 在单个SELECT中查询所需的所有数据。您可以通过匹配

      的要求来完成此操作
        

      ACTION_TYPE值不是“ - ”

      使用WHERE ACTION_TYPE <> '-'

    2. 的WHERE子句
    3. 对结果进行排序,以便按照“ADD”的预定顺序对其进行排序,然后“更改”,然后“删除”。您可以通过添加简单的ORDER BY ACTION_TYPE ASC

    4. 来完成此操作
    5. 循环遍历SqlDataReader.Read()并执行“控制中断”(我确定概念以各种名称命名)以应用新标头IF ACTION_TYPE的当前行的值与上一行不同。

    6. 在处理文件时将每一行写入文件。使用StreamWriter.WriteLine(String, Object, Object, Object)输出该行,同时对其进行格式化。

    7. 请注意:

      • 您可能需要调整_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();
      }
      

答案 1 :(得分:0)

每次在循环中调用File.WriteAllText时,都会覆盖以前的更改:

  

创建一个新文件,将内容写入该文件,然后关闭该文件。

     

如果目标文件已存在,则会被覆盖。

改为使用File.AppendAllText,因为会覆盖您的文件:

  

打开文件,将指定的字符串附加到文件,然后关闭文件。

修改后的代码:

File.AppendAllText(@"C:\BillingExport\EXPORTS\EFTHLDAY.TABLE.TYPE08.TRANSACTIONS.txt",
                   commaDelimitedText.ToString());

答案 2 :(得分:0)

替代方法是使用DataSet。 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

答案 3 :(得分:0)

您可以通过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());

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