1

我正在尝试使用 SQL Server 2016 中的 STUFF 功能来选择日期信息并将其返回到表中。有时会有多个日期返回。我已经使用 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,'')  

上面的代码片段只是示例,表名和变量名实际上是不同的,但它们应该传达我的意思。

最后一个代码片段的错误是由于“+”符号而无法工作。如果我把逗号加出来,我可以让它返回日期,但它们被包装在 XML 标记中。

它还必须返回一个 DATE 值,它不能转换为 NVARCHAR。

我不确定我所追求的是否可行,但我想我会问。

如果需要更多信息,请询问。

4

2 回答 2

1

评论太长了。

您的代码不能在单个列中返回多个日期值。SQL Server 不提供数组类型——或它们的等价物。

什么FOR XML PATH是产生一个字符串。该字符串被格式化为 XML,但它仍然是一个字符串。在字符串中,您可以识别属性的类型。但是,表示形式是字符串。

您可以做的最好的是将日期存储为 YYYY-MM-DD 或 YYYYMMDD,这很容易在 SQL Server(以及几乎任何其他软件)中转换为日期。

于 2019-01-29T11:45:06.350 回答
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 aREMOVE string function andSUBSTRING needs a length.STUFF`在附加新字符串之前删除指定数量的字符,因此它可以用于从开头删除文本。

于 2019-01-29T11:54:05.143 回答