【问题标题】:SQL Concatenation filling up tempDBSQL 连接填充 tempDB
【发布时间】:2011-08-23 11:08:04
【问题描述】:

我们正在尝试用单个查询连接 SQL 中可能有数千行的文本。我们目前的查询如下所示:

DECLARE @concatText NVARCHAR(MAX) 
SET @concatText = ''

UPDATE TOP (SELECT MAX(PageNumber) + 1 FROM #OrderedPages) [#OrderedPages] 
SET @concatText = @concatText + [ColumnText] + '
'
WHERE (RTRIM(LTRIM([ColumnText])) != '')

从功能的角度来看,这工作得很好。我们遇到的唯一问题是有时 ColumnText 可能有几千字节的长度。因此,当我们有数千个这样的行时,我们正在填满 tempDB。

我们想出的最佳理由是,当我们对@concatText 进行这些更新时,SQL 正在使用隐式事务,因此字符串实际上是不可变的。

我们正在尝试找出解决此问题的好方法,到目前为止,我们有两种可能的解决方案: 1)在.NET中进行连接。这是一个不错的选择,但有很多数据可能会通过网络返回。

2) 使用 .WRITE,其操作方式与 .NET 的 String.Join 方法类似。我无法弄清楚它的语法,因为 BoL 没有涵盖这种级别的 SQL 恶作剧。

这让我想到了一个问题:.WRITE 会起作用吗?如果是这样,语法是什么?如果没有,是否有任何其他方法可以在不向 .NET 发送数据的情况下执行此操作?我们不能使用FOR XML,因为我们的文本可能包含非法的 XML 字符。

提前致谢。

【问题讨论】:

  • 我从未见过解释TSQL 如何处理字符串的这种级别的文档。我对STUFF 的实验表明它没有比其他方法更优越的性能,所以我想也许所有字符串在 TSQL 中都是不可变的。不知道你的意思是“通过电线”。你不能在 SQL Server 中使用CLR 集成和用户定义的聚合吗?
  • 这种串联的目标是什么?你打算如何使用它?需要在数据库中做吗?

标签: sql concatenation tempdb


【解决方案1】:

同意..CLR 用户定义函数将是你们正在做的最好的方法。您实际上可以将文本值读入一个对象,然后将它们全部连接在一起(在 CLR 内部)并让函数吐出 NVARCHAR(MAX) 结果。如果您需要有关如何执行此操作的详细信息,请告诉我。

【讨论】:

    【解决方案2】:

    究竟是什么填满了 tempdb?它不能是@concatText = @concatText + [ColumnText],不涉及不变性,@concatText 变量在最坏的情况下将是 2GB 大小(我希望你的 tempdb 比这大得多,如果不增加它)。看起来您的查询计划更像是为万圣节保护创建了一个假脱机,而该假脱机是罪魁祸首。

    作为一个通用答案,已知使用UPDATE ... SET @var = @var + ... 进行连接存在正确性问题,因此不受支持。 Concatenating Row Values in Transact-SQL 中讨论了更可靠的替代方法。

    【讨论】:

      【解决方案3】:

      首先,从您的帖子来看,尚不清楚您是否需要或为什么需要临时表。连接可以在查询中内联完成。如果您向我们展示有关填充 tempdb 的查询的更多信息,我们也许可以帮助您重写它。其次,没有提到的一个选项是完全在 T-SQL 之外进行字符串操作。即,在您对原始数据的中间层查询中,进行操作并将其推回数据库。最后,您可以使用 Xml 以便结果正确处理转义和实体。同样,我们需要更多地了解您想要完成什么以及如何完成。

      【讨论】:

      • 有些字符会破坏所有 XML 方法。我不记得他们是什么了!
      • @Martin - 这会破坏 Xml 并且无法逃脱?我很想知道这些是什么。
      • @Thomas - CHAR(11)CHAR(27) AFAIK
      • 来自 RBarryYoung 对该线程的评论,它也适用于其他不可打印的控制字符。不确定您所说的编码/解码是什么意思 - 这是一些嵌套替换还是比这更复杂的东西?
      • @Martin - LF、CR 和 Tab 应该没问题。事实上,这是仅有的三个可以的不可打印文件。编码/解码实际上意味着对那些 Xml 阻塞的少数奇数字符进行一些嵌套替换。不会有那么多。
      【解决方案4】:

      我会考虑使用 CLR 集成,正如@Martin 的评论中所建议的那样。 CLR 聚合函数可能只是票证。

      【讨论】:

      • 我想我们最终会解决这个问题。我希望有一种简单的方法可以在不部署程序集的情况下在 SQL 上运行 .NET。就像 SQL 的 ASP.NET jitting 一样。
      猜你喜欢
      • 2012-02-14
      • 1970-01-01
      • 2013-05-17
      • 1970-01-01
      • 2021-08-25
      • 1970-01-01
      • 1970-01-01
      • 2023-04-11
      • 1970-01-01
      相关资源
      最近更新 更多