2013-11-15 29 views
2

我有一個存儲過程,將返回一列0或更多行或帳戶號碼。使用閱讀器將列提供給csv文件

如果0行我當然不需要做任何事情,但如果返回1或更多,我需要將這些帳號放入一個csv文件。

返回看起來像這樣的數據:

100000 
200000 
286598 

這裏是我的方法:

private static void ThirtyMinuteUpload(DateTime today) 
{ 
    using (SqlConnection connection = new SqlConnection(connString)) 
    { 
     using (SqlCommand command = new SqlCommand("mySP", connection)) 
     { 
      command.CommandType = CommandType.StoredProcedure; 

      connection.Open(); 
      if (command.ExecuteReader().HasRows) 
      { 
       // Create csv 
      } 
     } 
    } 
} 

我需要從我的讀者拋出那些成CSV和使用名稱這樣的文件today變量傳入:

exlcusion_mmddyyhhmmss.csv 

我從來沒有使用過文件creati現在它可以保存到我的桌面。這件事很容易做到嗎?

+0

你除了什麼類型的輸出?全部在一行(例A1:1000,B1:2000,C13000等)或全部在一列(A1:1000,A2:2000,A3:3000等等)? – Tinwor

回答

1

我會做這樣的事情:

更新:固定的最後一個逗號的問題。

using (SqlDataReader dr = command.ExecuteReader()) 
{ 
    if (dr.HasRows()) 
    {   
     string dateFormatted = today.ToString("MMddyyhhmmss"); 
     string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); 
     var writer = new StreamWriter(String.Format("{0}\exclusion_{1}.csv", 
     path, dateFormatted); 

     var cont = true; 
     while (cont) 
     { 
     // Grab the accountid before we read ahead 
     var accId = dr["accountid"]; 

     // Read ahead to check if we've read the last record 
     cont = dr.Read(); 

     // Last record, don't add comma 
     if (!cont) 
     { 
      writer.Write(accId); 
     } 
     else 
     { 
      writer.Write(accId + ","); 
     } 
     } 
    } 
} 
+0

我正在使用這個'作家。WriteLine(「{0}」,reader [「accountid」]);'如果它總是在最後一條記錄中添加一個逗號,會不會成爲問題? '100000,200000,' –

+0

'continue'是C#中的關鍵字,您應該使用'@ continue'代替。 –

+0

良好的通話!更新。 –

0
private static void ThirtyMinuteUpload(DateTime today) 
{ 
    using (var cn = new SqlConnection(connString)) 
    using (var cmd = new SqlCommand("mySP", cn)) 
    { 
     cmd.CommandType = CommandType.StoredProcedure; 
     cn.Open(); 

     using (var rdr = cmd.ExecuteReader()) 
     { 
      if (!rdr.HasRows) return; 

      var fileName = string.Format("{0}{1}exclusion_{2:MMddyyHHmmss}.csv", 
       Environment.GetFolderPath(Environment.SpecialFolder.Desktop), 
       Path.PathSeparator, 
       today); 

      using (var writer = new StreamWriter(fileName)) 
      { 
       while (rdr.Read()) 
       { 
        writer.WriteLine(rdr.GetString(0)); 
       } 
      } 
     } 
    } 
} 
0

這裏是一個更抽象的回答你的問題。我寫了一個通用函數,用於將任何System.Data.IDataReaderSystem.Data.SqlClient.SqlDataReader只是一個類)的實現者的數據寫入任何System.IO.Stream,其中包括文件(使用FileStream)。

/// <summary> 
/// Writes the data from a given <see cref="IDataReader"/> <paramref name="reader"/> to the <paramref name="output"/> <see cref="Stream"/>. 
/// There are optional parameters for writing a header, specifying the encoding, the buffer size, and whether or not the stream should be 
/// closed when we're done reading. 
/// </summary> 
/// <param name="reader">Any object which implements <see cref="IDataReader"/>-- most likely a <see cref="System.Data.SqlClient.SqlDataReader"/>.</param> 
/// <param name="output">The stream to output the CSV contents to.</param> 
/// <param name="writeHeader">When true, a header is written using the column names.</param> 
/// <param name="encoding">Optional parameter (defaulting to UTF8 without BOM) denoting how the data should be encoded.</param> 
/// <param name="bufferSize">Optional parameter (defaulting to 1KB) which is used as a buffer for writing the data.</param> 
/// <param name="closeOutput">Optional parameter which, when true, closes the <paramref name="output"/> <see cref="Stream"/> after we're doing writing.</param> 
private static void WriteCsv(IDataReader reader, Stream output, bool writeHeader = true, Encoding encoding = null, int bufferSize = 1024, bool closeOutput = false) 
{ 
    // If no encoding is provided, use the same one the StreamWriter defaults to. 
    if (encoding == null) 
     encoding = new UTF8Encoding(false, true); 

    // Create a new writer to our CSV file. 
    using (var writer = new StreamWriter(output, encoding, bufferSize, !closeOutput)) 
    { 
     // This will create an enumerable with every integer between 0 and FieldCount-1. 
     // Allows us to do a concise for loop and use String.Join to handle the comma placement. 
     var indices = Enumerable.Range(0, reader.FieldCount); 

     // Keep looping as long as their are rows returned by the reader. 
     while (reader.Read()) 
     { 
      // Write a header with the names of each column. 
      if (writeHeader) 
      { 
       writer.WriteLine(String.Join(",", indices.Select(i => reader.GetName(i) ?? ("column" + i)))); 
       writeHeader = false; 
      } 

      // Write the value of each field by its string representation separated by a comma. 
      writer.WriteLine(String.Join(",", indices.Select(i => (reader.IsDBNull(i) ? null : reader.GetString(i)) ?? ""))); 
     } 
    } 
} 

此功能讓你喜歡的編碼和什麼樣的你寫流的一些具體的控制大量(你可以寫一個HTTP響應或常規文件中,無所謂) 。如果您想要將更復雜的數據輸出到CSV文件中,我建議您通過CSV「標準」閱讀this article

這位作家是天真的 - 它只是寫入從IDataReader讀取的原始數據。如果您的內容有換行符,回車符或逗號,它可能會混淆最終消耗程序輸出的任何內容。我會編寫一個CsvEncode函數,您可以將每個值輸入,並根據上面的文章中列出的規則對其進行正確編碼。

這只是一個例子,而不是代碼,實際上應該使用:

private static string CsvEncode(string value) 
{ 
    // Handle commas within values. 
    if (value.Contains(',')) 
    { 
     // Strim so we get rid of beginning and trailing whitespaces we'd usually ignore. 
     value = value.Trim(); 

     // If the value is already wrapped with quotation marks but has quotation marks within as well, 
     if (value.StartsWith("\"") && value.EndsWith("\"") && value.IndexOf('\"', 1, value.Length-2) > 0) 
      value = "\"" + value.Substring(1, value.Length - 2).Replace("\"", "\"\"") + "\""; 
     else if (value.Contains("\"")) // Replace all quotations with two quotations, then wrap the final result. 
      value = "\"" + value.Replace("\"", "\"\"") + "\""; 
    } 
    return value; 
} 

而你也只需更新WriteCsv所以當它寫行的值,你調用CsvEncode,類似(只是舉個例子):

// Write the value of each field by its string representation separated by a comma. 
writer.WriteLine(String.Join(",", indices.Select(i => CsvEncode(reader.IsDBNull(i) ? "" : reader.GetString(i) ?? "")))); 

而只是爲了要徹底,這是你會怎麼稱呼它:

using (var reader = command.ExecuteReader()) 
{ 
    if (!reader.HasRows) 
     return; // Nothing to do. 

    // You want it on the desktop? We'll put it on the desktop. 
    var filePath = string.Format("{0}{1}exclusion_{2:MMddyyHHmmss}.csv", 
     Environment.GetFolderPath(Environment.SpecialFolder.Desktop), 
     Path.PathSeparator, 
     today); 

    // Pass in the reader we got from executing the command. File.Create will replace any 
    // existing files. closeOutput is true because we do not keep a reference to the FileStream. 
    WriteCsv(reader, File.Create(filePath), closeOutput: true);     
}