2012-10-03 6 views
13

मुझे SQL Server पर FILESTREAM कॉलम में बड़े डेटा की मात्रा लिखने में समस्या हो रही है। विशेष रूप से, 1.5-2 जीबी के आसपास छोटी फाइलों को ठीक से संभाला जाता है, लेकिन जब आकार 6 जीबी तक पहुंच जाता है, तो मुझे इंटरमीटेंटIOException हस्तांतरण के अंत में .CopyTo() पर "हैंडल अमान्य है" मिल रहा है।SQL सर्वर FILESTREAM में बड़ी फ़ाइलों को कैसे लिखें?

मैंने भाग में डेटा लिखने के बारे में सोचा है, लेकिन SQL सर्वर डेटा को जोड़ने की अनुमति देने से पहले क्षेत्र के लिए बैकिंग फ़ाइल की प्रतिलिपि बनाता है, जो बड़ी फ़ाइलों के लिए प्रदर्शन को पूरी तरह से नष्ट कर देता है।

public long AddFragment (string location , string description = null) 
{ 
    const string sql = 
     @"insert into [Fragment] ([Description],[Data]) " + 
      "values (@description,0x); " + 
     "select [Id], [Data].PathName(), " + 
      "GET_FILESTREAM_TRANSACTION_CONTEXT() " + 
     "from " + 
      "[Fragment] " + 
     "where " + 
      "[Id] = SCOPE_IDENTITY();"; 

    long id; 

    using (var scope = new TransactionScope(
     TransactionScopeOption.Required, 
      new TransactionOptions { 
       Timeout = TimeSpan.FromDays(1) 
      })) 
    { 
     using (var connection = new SqlConnection(m_ConnectionString)) 
     { 
      connection.Open(); 

      byte[] serverTx; 
      string serverLocation; 

      using (var command = new SqlCommand (sql, connection)) 
      { 
       command.Parameters.Add("@description", 
        SqlDbType.NVarChar).Value = description; 

       using (var reader = command.ExecuteReader()) 
       { 
        reader.Read(); 
        id = reader.GetSqlInt64(0).Value; 
        serverLocation = reader.GetSqlString (1).Value; 
        serverTx = reader.GetSqlBinary (2).Value; 
       } 
      } 

      using (var source = new FileStream(location, FileMode.Open, 
       FileAccess.Read, FileShare.Read, 4096, 
       FileOptions.SequentialScan)) 
      using (var target = new SqlFileStream(serverLocation, 
       serverTx, FileAccess.Write)) 
      { 
       source.CopyTo (target); 
      } 
     } 

     scope.Complete(); 
    } 

    return id; 
} 
+0

शायद http://msdn.microsoft.com/en-us/library/bb933972(v=sql.105 को देखने के अपने machine.config के विन्यास की स्थापना के लिए निम्न जोड़ने) .aspx – Paparazzi

+0

वहां एक सामान्य उदाहरण है जो फ़ील्ड में _9_ बाइट लिखता है। – chase

+0

शायद कनेक्शन पर एक टाइमआउट। उदाहरण के लिए आपने कनेक्शन टाइमआउट बढ़ाने का प्रयास किया था। बीटीडब्ल्यू, बस सोच रहा है, आप फ़ाइलों के लिए SQL सर्वर का उपयोग क्यों कर रहे हैं? क्या यह इन दिनों SQL सर्वर पर एक आम प्रथा बन रहा है? – ziya

उत्तर

3

मेरा सुझाव है आप अपने FileStream वर्ग के आसपास BufferedStream कक्षा का उपयोग करें:

कोड यह रहा।

यह भी सुनिश्चित करें कि आप SqlFileStream कक्षा पर WriteTimeOut संपत्ति सेट कर रहे हैं।

यहाँ आप एक बहुत अच्छी पोस्ट है कि SqlFileStream http://www.simple-talk.com/sql/learn-sql-server/an-introduction-to-sql-server-filestream/

+0

दस्तावेज़ों के बावजूद, WriteTimeout समर्थित नहीं है और अंतर्निहित स्ट्रीम से कम से कम 4.0 – user875318

+0

में एक अवैधऑपरेशन अपवाद फेंक देगा, जो कि शर्म की बात है, यह भी इंगित करने के लिए कि फ़ाइलस्ट्रीम पर bufferedstream का उपयोग करने के लिए इसकी आवश्यकता नहीं है, जैसा कि हाल के संस्करण से है। नेट बफरिंग कार्यक्षमता को फाइलस्ट्रीम में जोड़ा गया है। – dmportella

2

बारे में सब कुछ समझाने टिप्पणियों के कुछ लोगों द्वारा सुझाव दिया गया है लगता है यह समस्या शायद एक सौदे टाइमआउट है। आप SQL सर्वर प्रोफाइलर चलाकर और अपने लेन-देन को वापस लुढ़कने के लिए देखकर इसे सत्यापित कर सकते हैं।

अन्यथा निर्दिष्ट किए जाने तक, machine.config में 10 मिनट का डिफ़ॉल्ट अधिकतम टाइमआउट होता है, जिसे कोड के माध्यम से ओवरराइड नहीं किया जा सकता है। अधिकतम समय समाप्ति बढ़ाने के लिए,

<system.transactions> 
    <machineSettings maxTimeout="00:30:00" /> 
</system.transactions>