我的输出是正确的,但我想知道STUFF实际上是如何工作的。
我有一个简单的查询,它会返回@startDate
&之间的总月数。 @endDate
。
我在 STUFF 的帮助下将这几个月存入@cols。
查询是这样的:
SELECT DISTINCT ','
+ Quotename(CONVERT(CHAR(10), startdate, 120))
FROM #tempdates
这是我的输出:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX),
@startdate datetime = '1-Jan-2014',
@enddate datetime = '1-Jun-2014'
;with cte (StartDate, EndDate) as
(
select min(@startdate) StartDate, max(@enddate) EndDate
union all
select dateadd(mm, 1, StartDate), EndDate
from cte
where StartDate < EndDate
)
select StartDate
into #tempDates
from cte
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(convert(CHAR(10), StartDate, 120))
from #tempDates
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select @cols
drop table #tempDates
答案 0 :(得分:18)
Stuff对字符串起作用,它在你的SQL上做的唯一一件事是从位置1删除初始逗号。没有东西它看起来像a,b,c,d但是当你填充一个空值的位置它将其转换为a,b,c,d
您的问题可能更多是关于FOR XML正在做什么。在这种情况下,FOR XML
被用作“技巧”来连接来自#tempDates
的一个长逗号分隔字符串中的所有行,a,b,c,d和stuff只是删除了第一个逗号。
对于xml正在创建一个字符串x =',一个'+',b'+',c'+',d'所以x最终为',a,b,c,d'
Stuff(x,1,1,'')
仅将位置1中的逗号替换为“1”,因此现在x ='a,b,c,d'
[STUFF ( character_expression , start , length , replaceWith_expression )]