【问题标题】:SQL Server System.OutOfMemoryExceptionSQL Server System.OutOfMemoryException
【发布时间】:2018-08-08 09:09:10
【问题描述】:

我正在从 60 个表中生成 XML,并将这个 xml 存储在一个表中。

Table Name : Final_XML_Table

PK   FK    XML_Content (type xml)
1     1     "XML that I am generating from 60 tables"

当我在查询下运行时,它会出现内存异常:

Select * from Final_XML_Table

我尝试过的事情: 1. 文本结果:我在输出窗口中只从 XML 中获取几行文本作为文本 2. 归档结果:我只从文件中的 XML 中得到几行。

请提出建议,如果有任何更改,我是否必须在部署时在服务器的 SQL 服务器上执行此操作。

我还将 XML_Data 设置为无限制:

【问题讨论】:

  • 尝试右键单击查询,从上下文菜单中选择“选项”并在“结果”中打开“网格”区域。 XML 数据有一个选项。您可以将其设置为“无限制”。这将使用所有可以处理的内存。对于您的 XML,默认值可能很小...
  • 我已将 XML_DATA 设置为无限制。它仍然给出同样的错误
  • 你重启SSMS了吗?
  • 是的,但没有运气:( ...得到同样的错误

标签: sql-server xml xml-parsing


【解决方案1】:

这不是一个答案,而是一个评论......

您能够存储 XML 的事实清楚地表明,对于数据库来说,XML 并不是太大

Select * from Final_XML_Table 出现内存不足异常这一事实清楚地表明,SSMS 在读取/显示您的 XML 时存在问题。

您可以尝试像这里检查长度:

DECLARE @tbl TABLE (x XML);
INSERT INTO @tbl VALUES('<root><test>blah</test><test /><test2><x/></test2></root>');

SELECT * FROM @tbl;              --This does not work for you
SELECT DATALENGTH(x) FROM @tbl;  --This returns just "82" in this case

可能是由于您的 XML 创建中的逻辑错误(错误的连接?),XML 包含多个/重复的元素。您可以尝试这样的查询来获取节点数,以检查该数字是否真实:

SELECT x.value('count(//*)','int') FROM @tbl

对于上面的例子,返回“5”

您可以对原始 XML 执行相同的操作。

通过如下查询,您可以检索第一级、第二级等的所有节点名称。您可以检查这看起来是否正常:

SELECT firstLevel.value('local-name(.)','varchar(max)') AS l1_node
      ,SecondLevel.value('local-name(.)','varchar(max)') AS l2_node
      --add more
FROM @tbl
OUTER APPLY x.nodes('/*') AS A(firstLevel)
OUTER APPLY A.firstLevel.nodes('*') AS B(SecondLevel)
--add more

而且 - 当然 - 您可以打开 ResourceMonitor 来查看内存的实际使用情况...

回来看看更多细节...

【讨论】:

  • 非常感谢 .... datalength - 37708889 计数 - 928720 我确实看到了直到第 11 级,它看起来不错,直到第 11 级它提供了大约 710145 条记录。
  • 第一层和第二层与我的预期完全相同。
  • @JFI 我的语句有效的事实清楚地表明:SSMS 可以处理更大的 XML,因为这是由 SQL Server 完成的,但它不能显示这个大小,因为它仅限于 32 位地址。
  • 是的..这是真的......但在那种情况下,我如何能够在 ssms 上看到原始 XML,我用它来在表中插入数据......并且期望这个 xml 是相同的正如我正在生成的那样
  • @JFI 你检查过原件的 DATALENGTH 吗?
【解决方案2】:

该错误不是 SQL Server 错误,它来自 SSMS。这意味着 SSMS 内存不足。

SSMS 只是一个 32 位应用程序,因此只能寻址 2GB 的 RAM。如果它试图解决更多问题,则会发生错误。如果您打开了 SSMS 并返回了一些非常大的数据集,那么 RAM 将会被用完。

老实说,如果您正在运行像 SELECT * FROM Final_XML_Table 这样的查询,那么我会冒险猜测数据集是巨大的。添加WHERE 子句,或者不要在屏幕上返回数据集。如果您确实需要查看数据(全部),请将其导出到其他地方。但我非常怀疑您是否需要查看每一行,如果您返回大约 2GB 的数据。

【讨论】:

  • 表只有1条记录,它包含大约58k行代码的xml。
  • @JFI 如果您一直在运行其他查询,这也会增加 SSMS 正在使用的 RAM(因为它有时有不释放它的习惯)。 58K 的行虽然没有任何意义。如果每行只有 1-10 个字符,它就不会那么大,但如果每行有 500-1,000 个(空格 (' ') 也算作一个字符),那么大小会大得多。就像一个有 1 行和 1 列的表,它是一个已填充到容量的 nvarchar(MAX),远大于具有 8 列数据类型 bit 的表,具有 8000 万行。 (前者是 2GB,而另一个是 ~80MB)
  • 我有一个 3 mb 的 xml 文件,我已经在 60 个表中插入了这个 xml 的数据,现在我正在从表中重新生成 xml,我已经正确生成了 59 个表 xml,当我生成包含预期的完整 xml 的最终表,它给出了错误。所以xml的预期大小是3mb,插入到xml类型列的表中。
猜你喜欢
  • 2022-01-12
  • 1970-01-01
  • 2016-12-26
  • 2012-02-14
  • 1970-01-01
  • 2016-08-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多