У меня есть большой XML-файл (150mb range) на локальном диске и с использованием ADO.NET, чтобы поместить его в столбец nvarchar (max). Код выглядит так (сильно отредактированы так вещи, чтобы оставить только нужную часть кода):OutOfMemoryException с SQL XML Insert
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();
Я получаю эту проблему:
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()
Что является лучшим способом, чтобы получить этот большой диск XML на удаленном сервере БД?
Спасибо.
Насколько велики ваши xml-файлы? – dash
Файлы 150mb. Проблема заключается не только в одном файле, но при выполнении этого с несколькими задачами .NET (потоки) несколько могут потенциально запускаться одновременно, исчерпывая доступную память CLR. Благодарю. – Snowy
Когда я сохраняю большие файлы XML в базе данных, я использую двоичный тип данных и сначала сжимаю их - это удивительно, насколько компактен сжатый файл по сравнению с несжатым XML. При извлечении я просто распаковываю XML и доставляю его клиентам. Может предоставить образец, если хотите? Ваша альтернатива потенциально может поставить очередь на запросы; поэтому вы выполняете только пару сейвов одновременно. Возможно также иметь возможность передавать Xml, ограничивая количество в памяти за один раз. – dash