SQL Concatenation填满了tempDB

时间:2011-05-11 16:06:16

标签: sql concatenation tempdb

我们试图用一个查询连接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字符。

提前致谢。

4 个答案:

答案 0 :(得分:2)

我正在考虑使用CLR集成,正如@ Martin的评论中所建议的那样。 CLR聚合函数可能就是故障单。

答案 1 :(得分:1)

究竟是什么填补了tempdb?它不能是@concatText = @concatText + [ColumnText],不存在不变性,而@concatText变量在最坏的情况下是2GB大小(我希望你的tempdb远大于它,如果没有增加它)。看起来更像是你的查询计划为haloween保护创建一个假脱机,而假脱机是罪魁祸首。

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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