【问题标题】:OutOfMemoryException with SQL XML Insert带有 SQL XML 插入的 OutOfMemoryException
【发布时间】:2012-01-20 21:50:47
【问题描述】:

我在本地磁盘上有一个大型 XML 文件(150mb 范围),并使用 ADO.NET 将其放入 nvarchar(max) 列。代码看起来像这样(经过大量编辑,只留下代码的相关部分):

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 导入远程 DB 服务器的最佳方法是什么?

谢谢。

【问题讨论】:

  • 文件为 150mb。问题不只是一个文件,而是当使用多个 .NET 任务(线程)执行此操作时,可能会同时运行多个文件,从而耗尽 CLR 可用内存。谢谢。
  • 当我将大型 XML 文件保存到数据库时,我使用二进制数据类型并首先对其进行压缩——令人惊讶的是,压缩文件与未压缩的 XML 相比有多小。在检索时,我只需解压缩 XML 并将其交付给客户端。如果您愿意,可以提供样品吗?您的替代方案可能是对请求进行排队;所以你一次只能进行几次保存。可能还可以流式传输 Xml,一次限制内存量。

标签: sql-server-2008 ado.net stream sqlxml


【解决方案1】:

如果没有像您看到 SQL连接对象不在Using语句中+SqlCommand类也是IDisposable。

这可能不是每次都会出现内存溢出崩溃的问题。但是当内存溢出时肯定会出现问题......

【讨论】:

    猜你喜欢
    • 2017-08-03
    • 1970-01-01
    • 2014-06-06
    • 2013-01-28
    • 1970-01-01
    • 1970-01-01
    • 2012-10-08
    • 1970-01-01
    • 2011-04-19
    相关资源
    最近更新 更多