2010-03-17 17 views
5

मान लीजिए कि मेरे पास एक VarBinary [MAX] कॉलम है, क्या मैं System.IO.Stream से व्युत्पन्न प्रकार का उपयोग करके उस कॉलम में डाल या अपडेट कर सकता हूं? कैसे?क्या मैं SQL सर्वर (सी #) में एक पंक्ति का उपयोग INSERT या अद्यतन कर सकता हूं?

मुझे लगता है कि मैं एक SqlDataReader का उपयोग कर, पाठक पर GetSqlBytes() बुला, SqlBytes उदाहरण हो रही, और फिर उस पर Stream संपत्ति को संदर्भित इस तरह के एक स्तंभ से एक केवल पढ़ने के लिए धारा प्राप्त कर सकते हैं।

जो मैं चाहता हूं वह बातचीत है - मुझे अपडेट या डालने के लिए एक स्ट्रीम चाहिए।

संभव है? (ग # से ... T-SQL लेखन के बिना?)


संपादित

मैं इस तरह कोड को देखा है:

System.Data.SqlClient.SqlCommand _SqlCommand 
     = new System.Data.SqlClient.SqlCommand(_SQL, _SqlConnection); 

    // Convert image to memory stream 
    System.IO.MemoryStream _MemoryStream = new System.IO.MemoryStream(); 
    _Image.Save(_MemoryStream, _ImageFormat); 

    // Add image as SQL parameter 
    System.Data.SqlClient.SqlParameter _SqlParameter 
     = new System.Data.SqlClient.SqlParameter("@" + _ImageFieldName, SqlDbType.Image); 

    _SqlParameter.Value = _MemoryStream.ToArray(); 
    _SqlCommand.Parameters.Add(_SqlParameter); 

    // Executes a Transact-SQL statement against the connection 
    // and returns the number of rows affected. 
    _SqlRetVal = _SqlCommand.ExecuteNonQuery(); 

    // Dispose command 
    _SqlCommand.Dispose(); 
    _SqlCommand = null; 

... लेकिन मुझे नहीं पता मान निर्दिष्ट करने के लिए एक सरणी का उपयोग करना चाहते हैं। यह छोटे डेटा आकारों के लिए काम करता है, लेकिन आकार जितना बड़ा नहीं होता है। मैं एक धारा में लिखना चाहता हूँ।

+0

https://stackoverflow.com/questions/2101149/how-to-i-serialize-a-large-graph-of-net-object-into-a-sql-server-blob-without/2151491# देखें उदाहरण के लिए 21514 9 1 बीओएलबी –

उत्तर

7

पर पैरामीटर के रूप में के पैरामीटर के रूप में आपको SqlBytes का उदाहरण पास करने में सक्षम होना चाहिए। वही SqlBytes कक्षा में constructor overload है जो Stream को लपेटता है। तो बस स्ट्रीम से SqlBytes उदाहरण बनाएं, फिर पैरामीटर मान के रूप में पास करें।

दूसरे शब्दों में, फिटिंग है कि आपके संशोधित कोड में हैं, तब यह की:

MemoryStream _MemoryStream = new System.IO.MemoryStream(); 
_Image.Save(_MemoryStream, _ImageFormat); 
SqlParameter _SqlParameter = new 
    SqlParameter("@" + _ImageFieldName, SqlDbType.Image); 
_SqlParameter.Value = _MemoryStream.ToArray(); 
_SqlCommand.Parameters.Add(_SqlParameter); 

उपयोग करें:

MemoryStream _MemoryStream = new System.IO.MemoryStream(); 
_Image.Save(_MemoryStream, _ImageFormat); 
_MemoryStream.Position = 0; // I *think* you need this 
SqlParameter _SqlParameter = new 
    SqlParameter("@" + _ImageFieldName, SqlDbType.VarBinary); 
_SqlParameter.Value = new SqlBytes(_MemoryStream); 
_SqlCommand.Parameters.Add(_SqlParameter); 
बेशक

, मत भूलना MemoryStream और इन सभी निपटान के लिए आदेश के बाद अन्य IDisposable उदाहरण निष्पादित किए गए हैं।


संपादित करें: ठीक है, मैं सिर्फ अपने संपादित करें, जो जिसका अर्थ है कि डेटा बहुत बड़ी है और आप इसे स्मृति में समाप्त नहीं करना चाहती के नीचे देखा, और यह वास्तव में उस का समाधान नहीं होगा मुसीबत। बात यह है कि, यदि मूल्य इतना बड़ा है, तो इसे पहले स्थान पर varbinary कॉलम में संग्रहीत करना एक बुरा विचार है।

यदि आप SQL Server 2008 का उपयोग कर रहे हैं, तो आप इसके बजाय FILESTREAM का उपयोग कर सकते हैं (और चाहिए!)। यह वास्तव में में SqlFileStream कक्षा के माध्यम से "सत्य" स्ट्रीमिंग का समर्थन करता है।

यदि आप FILESTREAM संग्रहण का उपयोग नहीं कर सकते हैं, तो मुझे डर है कि आपको कुछ समय पर स्मृति में डेटा से निपटना होगा, यह बहुत कुछ है कि ADO.NET कैसे काम करता है।

+0

हारून में लिखने के लिए स्ट्रीमिंग सेमेन्टिक्स का उपयोग कैसे करें, धन्यवाद। UPDATETEXT के बारे में क्या? (Http://msdn.microsoft.com/en-us/library/3517w44b.aspx देखें) क्या मैं इसे ऑफसेट के साथ उपयोग नहीं कर सकता और स्मृति में सभी डेटा को एक समय में रखने की समस्या से बच सकता हूं? मैं भाग में डेटा लिखूंगा। – Cheeso

+0

@ चेसियो: ऐसा लगता है कि रीमस ने 'WRITE' का उपयोग करके इस बारे में पोस्ट किया है, जो समान है। मैंने वास्तव में उस कोण से समस्या के बारे में सोचा नहीं था; एक 'INSERT' या 'UPDATE' (जो कि केवल नहीं किया जा सकता है) में पैरामीटर के रूप में ADO.NET को स्ट्रीम पास करने का प्रयास करने के बजाय, आप वास्तव में एक बीज' INSERT'/'UPDATE' निष्पादित करते हैं और फिर कई लगातार' अद्यतन ... लिखने के बयान (जो प्रतिस्थापन, ब्लॉब डेटा के बजाय, जोड़ता है)। यदि आप बहु-कथन कार्यान्वयन के साथ ठीक हैं तो मैं शायद उसका जवाब स्वीकार करूंगा। – Aaronaught

1

vladimir-khozeyev How to I serialize a large graph of .NET object into a SQL Server BLOB without creating a large buffer? के उत्तर में बताए गए कि आपको .NET Framework 4 का उपयोग करते समय स्ट्रीम की आवश्यकता है।5 SqlClient Streaming Support

एसक्यूएल कोड:

CREATE TABLE BigFiles 
(
    [BigDataID] [int] IDENTITY(1,1) NOT NULL, 
    [Data] VARBINARY(MAX) NULL 
) 

सी # कोड:

using (FileStream sourceStream = new FileStream(filePath, FileMode.Open)) 
{ 
    using (SqlCommand cmd = new SqlCommand(string.Format("UPDATE BigFiles SET [email protected] WHERE BigDataID = @BigDataID"), _sqlConn)) 
    { 
     cmd.Parameters.AddWithValue("@Data", sourceStream); 
     cmd.Parameters.AddWithValue("@BigDataID", entryId); 

     cmd.ExecuteNonQuery(); 
    } 
} 

इस कोड को विंडोज 7 पर काम करता है, लेकिन Windows XP और 2003 सर्वर पर विफल रही है।

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

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