2014-10-31 141 views
0

我有一个表名称为ACTION_TYPE的字段。它的潜在值是“ADD”,“Change”,“DELETE”和“ - ”。我想要导出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条目现在位于已创建文件的底部)。

+0

更快,更容易的解决方案将使用SSIS并将查询结果导出到CSV文件。这也将避免在写回到磁盘之前加载内存中的所有内容 – 2014-10-31 13:49:48

回答

2

是的,有是不需要更好的办法:

  1. 复制代码
  2. 在集到内存整个结果拉(即在DataTable
  3. 复制整个结果在内存中重新设置,但在StringBuilder

一般概念的形式是:

  1. 查询所有的数据,你在一个单一的希望选择。通过使用WHERE WHERE ACTION_TYPE <> '-'

  2. 排序的子句的结果,让你得到他们

    - 您可以通过匹配您的

    ACTION_TYPE值不是都需要做到这一点“”按照“添加”的预定顺序,然后“更改”,然后“删除”。您可以通过SqlDataReader.Read()添加一个简单的ORDER BY ACTION_TYPE ASC

  3. 循环做到这一点,做一个“控制中断”(我敢肯定,这个概念的推移,各种名称)以应用新标头如果当前行的为ACTION_TYPE值与前一行不同。

  4. 在处理文件时将每行写出到文件中。使用StreamWriter.WriteLine(String, Object, Object, Object)在输出行的同时格式化它。

请注意:

  • 您可能需要我有没有洞察到的模式,我不知道哪列是ACTION_TYPE
  • 建议调整_Reader.GetString调用的索引值明确地按名称选择字段,而不是使用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(); 
} 
+0

@ bob-francis请使用评论发布信息。消息是:我试图实现这一点,虽然它对我有很多错误。我做了一些调整,现在我剩下3个错误,这是行[]调用的3个实例(名称行在当前上下文中不存在)。 – 2014-10-31 14:50:30

+0

我将行[1]更改为_Reader [1],2等。测试完成后效果良好。谢谢! – 2014-10-31 14:50:57

+0

@ bob-francis:我更新了'_reader.GetInt32()'交换'row []'的代码。对于那个很抱歉。这些字段真的是INT值吗?否则,可以很容易地改变'GetXXXX()'以适应适当的数据类型。 – 2014-10-31 14:52:12

0

每次你在你的循环调用File.WriteAllText时,你就覆盖以前的变化:

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

如果目标文件已经存在,它将被覆盖。

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

打开一个文件,将指定字符串的文件,然后关闭该文件。

修改后的代码:

File.AppendAllText(@"C:\BillingExport\EXPORTS\EFTHLDAY.TABLE.TYPE08.TRANSACTIONS.txt", 
        commaDelimitedText.ToString()); 
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()); 

我写的,但不尝试,它可能工作