2012-01-29 5 views
6

मेरे पास सी # में एक दूरस्थ एसक्यूएल कनेक्शन है जिसे एक क्वेरी निष्पादित करने की आवश्यकता है और इसके परिणाम उपयोगकर्ताओं की स्थानीय हार्ड डिस्क पर सहेजने की आवश्यकता है। इस बात की वापसी की जा सकने वाली डेटा की काफी बड़ी मात्रा है, इसलिए इसे संग्रहीत करने के एक कुशल तरीके के बारे में सोचने की आवश्यकता है। मैंने पहले पूरे परिणाम को स्मृति में डालने से पहले पढ़ा है और फिर इसे लिखना अच्छा विचार नहीं है, इसलिए यदि कोई मदद कर सकता है, तो बहुत अच्छा होगा!सी # में एसक्यूएल डाटाएडर से फ़ाइल को कुशलतापूर्वक लिखने के लिए कैसे लिखें?

  DataTable t = new DataTable(); 
      string myQuery = QueryLoader.ReadQueryFromFileWithBdateEdate(@"Resources\qrs\qryssysblo.q", newdate, newdate); 
      using (SqlDataAdapter a = new SqlDataAdapter(myQuery, sqlconn.myConnection)) 
      { 
       a.Fill(t); 
      } 

      var result = string.Empty; 
    for(int i = 0; i < t.Rows.Count; i++) 
    { 
     for (int j = 0; j < t.Columns.Count; j++) 
     { 
      result += t.Rows[i][j] + ","; 
     } 


     result += "\r\n"; 
    } 

तो अब मैं इस है:

मैं वर्तमान में, एक DataTable में एसक्यूएल परिणाम डेटा भंडारण कर रहा हूँ, हालांकि मैं यह बेहतर while(myReader.Read(){...} नीचे में कुछ कर रही हो सकता है सोच रहा हूँ कोड है कि परिणाम हो जाता है विशाल परिणाम स्ट्रिंग। और मेरे पास डेटाटेबल है। ऐसा करने का एक बेहतर तरीका होना चाहिए?

धन्यवाद।

+0

http://stackoverflow.com/questions/2244655/how-to-serialize-a-datatable-to-a-string –

+0

का संभावित डुप्लिकेट क्या आप सिर्फ एक गैर प्रारूपित फ्लैट फ़ाइल पर लिख रहे हैं, या यह बेहतर होगा डेटा को .csv स्प्रेडशीट जैसे स्तंभों में रखें? – DOK

+0

फ्लैट कॉमा-डेल फ़ाइल। – Sam

उत्तर

18

आप अपने आप को सही रास्ते पर हैं। while(myReader.Read(){...} के साथ एक लूप का उपयोग करें और लूप के अंदर पाठ फ़ाइल में प्रत्येक रिकॉर्ड लिखें। .NET फ्रेमवर्क और ऑपरेटिंग सिस्टम बफर को डिस्क पर एक कुशल तरीके से फ़्लश करने का ख्याल रखेगा।

using(SqlConnection conn = new SqlConnection(connectionString)) 
using(SqlCommand cmd = conn.CreateCommand()) 
{ 
    conn.Open(); 
    cmd.CommandText = QueryLoader.ReadQueryFromFileWithBdateEdate(
    @"Resources\qrs\qryssysblo.q", newdate, newdate); 

    using(SqlDataReader reader = cmd.ExecuteReader()) 
    using(StreamWriter writer = new StreamWriter("c:\temp\file.txt")) 
    { 
    while(reader.Read()) 
    { 
     // Using Name and Phone as example columns. 
     writer.WriteLine("Name: {0}, Phone : {1}", 
     reader["Name"], reader["Phone"]); 
    } 
    } 
} 
+0

धन्यवाद। मुझे किस लेखन विधि का उपयोग करना चाहिए? StreamWriter? आईओ? एक उदाहरण बहुत उपयोगी होगा। धन्यवाद – Sam

+0

यदि आप किसी फ़ाइल को लिखना चाहते हैं तो StreamWriter का उपयोग करें। एक उदाहरण के साथ मेरा अद्यतन देखें। –

+0

धन्यवाद। सभी पंक्तियों के लिए मैं उपयोग कर रहा हूं: 'स्ट्रिंगबिल्डर पंक्ति = नया स्ट्रिंगबिल्डर(); (int i = 0; i Sam

2

मैं मानता हूँ कि अपने सबसे अच्छे यहाँ शर्त एक SqlDataReader उपयोग करने के लिए किया जाएगा। कुछ इस तरह:

StreamWriter YourWriter = new StreamWriter(@"c:\testfile.txt"); 
SqlCommand YourCommand = new SqlCommand(); 
SqlConnection YourConnection = new SqlConnection(YourConnectionString); 
YourCommand.Connection = YourConnection; 
YourCommand.CommandText = myQuery; 

YourConnection.Open(); 

using (YourConnection) 
{ 
    using (SqlDataReader sdr = YourCommand.ExecuteReader()) 
     using (YourWriter) 
     { 
      while (sdr.Read()) 
       YourWriter.WriteLine(sdr[0].ToString() + sdr[1].ToString() + ","); 

     } 
} 

मन आप, while पाश में, आप किसी भी प्रारूप आप SqlDataReader से स्तंभ डेटा के साथ मनचाहे ढंग में पाठ फ़ाइल में है कि लाइन लिख सकते हैं।

1

मैं इस के साथ आया था, यह अन्य उत्तर तुलना में एक बेहतर सीएसवी लेखक है:

public static class DataReaderExtension 
{ 
    public static void ToCsv(this IDataReader dataReader, string fileName, bool includeHeaderAsFirstRow) 
    { 

     const string Separator = ","; 

     StreamWriter streamWriter = new StreamWriter(fileName); 

     StringBuilder sb = null; 

     if (includeHeaderAsFirstRow) 
     { 
      sb = new StringBuilder(); 
      for (int index = 0; index < dataReader.FieldCount; index++) 
      { 
       if (dataReader.GetName(index) != null) 
        sb.Append(dataReader.GetName(index)); 

       if (index < dataReader.FieldCount - 1) 
        sb.Append(Separator); 
      } 
      streamWriter.WriteLine(sb.ToString()); 
     } 

     while (dataReader.Read()) 
     { 
      sb = new StringBuilder(); 
      for (int index = 0; index < dataReader.FieldCount; index++) 
      { 
       if (!dataReader.IsDBNull(index)) 
       { 
        string value = dataReader.GetValue(index).ToString(); 
        if (dataReader.GetFieldType(index) == typeof(String)) 
        { 
         if (value.IndexOf("\"") >= 0) 
          value = value.Replace("\"", "\"\""); 

         if (value.IndexOf(Separator) >= 0) 
          value = "\"" + value + "\""; 
        } 
        sb.Append(value); 
       } 

       if (index < dataReader.FieldCount - 1) 
        sb.Append(Separator); 
      } 

      if (!dataReader.IsDBNull(dataReader.FieldCount - 1)) 
       sb.Append(dataReader.GetValue(dataReader.FieldCount - 1).ToString().Replace(Separator, " ")); 

      streamWriter.WriteLine(sb.ToString()); 
     } 
     dataReader.Close(); 
     streamWriter.Close(); 
    } 
} 

उपयोग: mydataReader.ToCsv ("myfile.csv", true)

+1

आप '- 1' के लिए' int (int index = 0; अनुक्रमणिका vapcguy

+1

@vacguy धन्यवाद नहीं है मैंने अपना उत्तर –

2

रोब सिडगविक जवाब अधिक है इस तरह, लेकिन सुधार और सरलीकृत किया जा सकता है। इस तरह मैंने किया है:

string separator = ";"; 
string fieldDelimiter = ""; 
bool useHeaders = true; 

string connectionString = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; 

using (SqlConnection conn = new SqlConnection(connectionString)) 
{ 
    using (SqlCommand cmd = conn.CreateCommand()) 
    { 
      conn.Open(); 
      string query = @"SELECT whatever"; 

      cmd.CommandText = query; 

      using (SqlDataReader reader = cmd.ExecuteReader()) 
      { 
       if (!reader.Read()) 
       { 
        return; 
       } 

       List<string> columnNames = GetColumnNames(reader); 

       // Write headers if required 
       if (useHeaders) 
       { 
        first = true; 
        foreach (string columnName in columnNames) 
        { 
          response.Write(first ? string.Empty : separator); 
          line = string.Format("{0}{1}{2}", fieldDelimiter, columnName, fieldDelimiter); 
          response.Write(line); 
          first = false; 
        } 

        response.Write("\n"); 
       } 

       // Write all records 
       do 
       { 
        first = true; 
        foreach (string columnName in columnNames) 
        { 
          response.Write(first ? string.Empty : separator); 
          string value = reader[columnName] == null ? string.Empty : reader[columnName].ToString(); 
          line = string.Format("{0}{1}{2}", fieldDelimiter, value, fieldDelimiter); 
          response.Write(line); 
          first = false; 
        } 

        response.Write("\n"); 
       } 
       while (reader.Read()); 
      } 
    } 
} 

और तुम एक समारोह GetColumnNames की आवश्यकता है: बाहर पेज लेखन के HTML कुछ मामलों में कम से कम एक response.Close() कारणों के बिना

List<string> GetColumnNames(IDataReader reader) 
{ 
    List<string> columnNames = new List<string>(); 
    for (int i = 0; i < reader.FieldCount; i++) 
    { 
     columnNames.Add(reader.GetName(i)); 
    } 

    return columnNames; 
} 
1

प्रतिक्रिया ऑब्जेक्ट का उपयोग करना डेटा को फ़ाइल में लिखा जाना है। आप Response.Close() का उपयोग करते हैं कनेक्शन समय से पहले ही बंद किया जा सकता है और फ़ाइल का निर्माण एक त्रुटि का कारण है।

यह HttpApplication.CompleteRequest() लेकिन यह हमेशा पैदा करने के लिए html फ़ाइल के अंत में लिखा जा प्रतीत होता है उपयोग करने के लिए सिफारिश की है।

मैं प्रतिक्रिया वस्तु के साथ संयोजन के रूप में धारा की कोशिश की है और विकास के वातावरण में सफलता मिली है। मैं अभी तक उत्पादन में इसे करने की कोशिश नहीं की है।

इसके बजाय एक अस्थायी बफर के रूप में स्ट्रिंग का उपयोग कर के, StringBuilder का उपयोग करें:

2

अपने मूल दृष्टिकोण है, यहाँ रखते हुए एक त्वरित जीत है। यही कारण है कि आप के बजाय ऑपरेटर += का उपयोग कर के, concatenations के लिए समारोह .append(String) उपयोग करने के लिए अनुमति देगा।

ऑपरेटर += विशेष रूप से अक्षम है, इसलिए यदि आप इसे लूप पर रखते हैं और इसे बार-बार (संभावित रूप से) लाखों बार दोहराया जाता है, तो प्रदर्शन प्रभावित होगा।

.append(String) विधि मूल वस्तु को नष्ट नहीं होगा, इसलिए यह तेजी से

1

मैं .CSV इस्तेमाल किया DataReader द्वारा डेटाबेस से डेटा निर्यात करने के लिए। मेरी परियोजना में मैंने डेटरेडर पढ़ा और सीएसवी फ़ाइल मैनुअल बनाया। एक लूप में मैं डेटारेडर पढ़ता हूं और प्रत्येक पंक्तियों के लिए मैं परिणाम स्ट्रिंग के लिए सेल मान जोड़ता हूं। अलग-अलग स्तंभों के लिए मैं "," का उपयोग करता हूं और अलग-अलग पंक्तियों के लिए मैं "\ n" का उपयोग करता हूं। अंत में मैंने परिणाम स्ट्रिंग को परिणाम.csv के रूप में सहेजा।

मैं इस high performance extension का सुझाव देता हूं। मैंने इसका परीक्षण किया और जल्दी से 600,000 पंक्तियों को सीएसवी के रूप में निर्यात किया।

+0

सही किया है, जबकि यह लिंक प्रश्न का उत्तर दे सकता है, यहां उत्तर के आवश्यक हिस्सों को शामिल करना बेहतर है और संदर्भ के लिए लिंक प्रदान करना बेहतर है। लिंक किए गए पृष्ठ में परिवर्तन होने पर लिंक-केवल उत्तर अमान्य हो सकते हैं। - [समीक्षा से] (/ समीक्षा/कम गुणवत्ता वाली पोस्ट/1620 9 261) –

+0

आपकी टिप्पणी के लिए धन्यवाद। मैंने अपना जवाब पूरा कर लिया – Nigje

संबंधित मुद्दे