2012-01-20 17 views
0

ローカルディスクに大きなXMLファイル(150mbの範囲)があり、ADO.NETを使用してnvarchar(max)列に配置しています。この大容量のディスクを取得するための最良の方法です何OutOfMemoryException with SQL XML Insert

ExceptionBody:System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown. 
    at System.IO.MemoryStream.set_Capacity(Int32 value) 
    at System.IO.MemoryStream.EnsureCapacity(Int32 value) 
    at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) 
    at System.Xml.XmlEncodedRawTextWriter.EncodeChars(Int32 startOffset, Int32 endOffset, Boolean writeAllToStream) 
    at System.Xml.XmlEncodedRawTextWriter.FlushBuffer() 
    at System.Xml.XmlEncodedRawTextWriter.RawText(Char* pSrcBegin, Char* pSrcEnd) 
    at System.Xml.XmlEncodedRawTextWriter.RawText(String s) 
    at System.Xml.XmlEncodedRawTextWriter.WriteStartElement(String prefix, String localName, String ns) 
    at System.Xml.XmlWellFormedWriter.WriteStartElement(String prefix, String localName, String ns) 
    at System.Xml.XmlWriter.WriteNode(XmlReader reader, Boolean defattr) 
    at System.Data.SqlTypes.SqlXml.CreateMemoryStreamFromXmlReader(XmlReader reader) 
    at System.Data.SqlTypes.SqlXml..ctor(XmlReader value) 
    at System.Data.SqlClient.SqlParameter.CoerceValue(Object value, MetaType destinationType) 
    at System.Data.SqlClient.SqlParameter.GetCoercedValue() 
    at System.Data.SqlClient.SqlParameter.Validate(Int32 index, Boolean isCommandProc) 
    at System.Data.SqlClient.SqlCommand.SetUpRPCParameters(_SqlRPC rpc, Int32 startCount, Boolean inSchema, SqlParameterCollection parameters) 
    at System.Data.SqlClient.SqlCommand.BuildRPC(Boolean inSchema, SqlParameterCollection parameters, _SqlRPC& rpc) 
    at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) 
    at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) 
    at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) 
    at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 

:私はこの問題を取得

using (var fileStream = new FileStream(myfile , FileMode.Open , FileAccess.Read , FileShare.Read)) 
{ 
// prep sqlconnection... 
sqlCon.Open(); 
var sqlCommand = new SqlCommand();  
sqlCommand.Connection = sqlCon; 
sqlCommand.CommandType = CommandType.StoredProcedure; 
sqlCommand.CommandText = "[dbo].[bigsproc]"; 
var param1 = new SqlParameter("@doc" , SqlDbType.NVarChar , Int32.MaxValue); 
param1.Value = new SqlXml(fileStream); 
sqlCommand.Parameters.Add(param1); 
var syncResult = sqlCommand.ExecuteNonQuery(); 

:(ものはコードのほんの関連部分を残すようにして頻繁に編集された)のコードは次のようになりますベースのXMLをリモートDBサーバーにインポートする

ありがとうございました。

+2

あなたのXMLファイルの大きさはどれくらいですか? – dash

+0

ファイルは150MBです。この問題は1つのファイルだけではありませんが、複数の.NETタスク(スレッド)でこれを実行すると、同時に複数のスレッドが同時に実行され、CLRの使用可能なメモリが使い果たされる可能性があります。ありがとう。 – Snowy

+0

大規模なXMLファイルをデータベースに保存すると、バイナリデータ型を使用して最初に圧縮します。圧縮されたファイルと圧縮されていないXMLがどれほど小さいかは驚くべきことです。取得時に、私は単にXMLを解凍してクライアントに配信します。あなたが好きならサンプルを提供できますか?あなたの選択肢は潜在的に要求をキューに入れることです。一度に2つのセーブを実行するだけです。 Xmlをストリームして、一度にメモリ内の量を制限することもできます。 – dash

答えて

0

SQL接続オブジェクトがUsingステートメントにない+ SqlCommandクラスもIDisposableであると見なされた場合のようにオブジェクトが破棄されないとメモリが異常終了します。

これは、常にメモリオーバーフロークラッシュではない可能性があります。しかし、問題は間違いなくメモリがオーバーフローするときに来る...