我正在尝试使用SQL Server 2016中的STUFF功能来选择DATE信息并将其返回到表中。有时会有多个日期可以返回。我已经使用STUFF来获取所需的其他数据。
Email = STUFF((SELECT ', ' + [Value]
FROM EmailTable
WHERE ID = r.ID AND EmailType = 1
FOR XML PATH(''),TYPE).value('(./text())[1]','NVARCHAR(MAX)'),1,2,'')
这可以在适用的情况下返回多封电子邮件,并且效果很好。现在的问题是我想做同样的事情,但是要有一个DATE。
Date = STUFF((SELECT ', ' + DateValue
FROM DateTable
WHERE ID = r.ID
FOR XML PATH(''),TYPE).value('(./text())[1]','DATE'),1,2,'')
上面的代码片段只是示例,表和变量名称实际上是不同的,但是它们应该传达我的理解。
最后一个代码段的错误是由于'+'符号,它无法正常工作。如果我用逗号加上加号,我可以得到它返回DATE,但是它们被封装在XML标记中。
此外,它还必须返回DATE值,无法将其转换为NVARCHAR。
我不确定我追求的目标是否可行,但我想问一下。
如果需要更多信息,请询问。
答案 0 :(得分:1)
这个评论太长了。
您的代码不能在单个列中返回多个日期值。 SQL Server不提供数组类型-或它们的等效类型。
FOR XML PATH
的作用是产生一个 string 。该字符串的格式为XML,但仍为字符串。在字符串中,您可以标识属性的类型。但是,表示形式是字符串。
最好的办法是将日期存储为YYYY-MM-DD或YYYYMMDD,可以很容易地将其转换为SQL Server(以及几乎所有其他软件)中的日期。
答案 1 :(得分:1)
您发布的内容采用了旧SQL Server版本中使用的字符串聚合技术。 SQL Server 2017为此提供了STRING_AGG。
此技术使用空字符串作为元素名称从查询生成XML值。最后的.value('(./text())[1]','NVARCHAR(MAX)')
将XML值转换为text。最后,STUFF, 1,2,'')
删除了前导定界符。
由于您要连接字符串,并且不想让日期格式出现问题,因此可以使用FORMAT()将日期格式化为所需的字符串:
Email = STUFF((SELECT ', ' + FORMAT([DateValue],'yyyy-MM-dd')
FROM EmailTable
WHERE ID = r.ID AND EmailType = 1
FOR XML PATH(''),TYPE
).value('(./text())[1]','NVARCHAR(MAX)'),
1,2,'')
工作方式
以x
作为元素名称执行最里面的查询:
SELECT ', ' + format(DateValue,'yyyy-MM-dd')
FROM EmailTable
WHERE year=2019 and Day<5 and month=1
FOR XML PATH('x'),TYPE
会返回:
<x>, 2019-01-01</x>
<x>, 2019-01-02</x>
<x>, 2019-01-03</x>
<x>, 2019-01-04</x>
通过指定空字符串作为元素,我们得到:
, 2019-01-01, 2019-01-02, 2019-01-03, 2019-01-04
那仍然是一个XML值,其内部文本是我们想要的字符串。我们需要使用.value('(./text())[1]','nvarchar(max)')
提取它:
select ( SELECT ', ' + format(DateValue,'yyyy-MM-dd')
FROM EmailTable
WHERE year=2019 and Day<5 and month=1
FOR XML PATH(''),TYPE
).value('(./text())[1]','nvarchar(max)')
此后,我们需要删除前导定界符,在这种情况下,两个字符的. T-SQL doesn't have a
REMOVE string function and
SUBSTRING needs a length.
STUFF` 删除附加新字符串之前的字符数,因此可用于从头开始删除文本。