在SQL Server中用JSON连接/聚合字符串

在SQL Server中用JSON连接/聚合字符串,sql,json,sql-server,xml,Sql,Json,Sql Server,Xml,对于那些在SQLServer中使用JSON有经验的人来说,这可能是一个简单的问题。我在中发现了使用FOR XML聚合字符串的有趣方法 如何使用JSON而不是XML实现同样的功能 不能用JSON替代XML方法。这种字符串连接的工作原理是由于一些XML内部特性,这些特性在JSON中是不同的 从SQL Server 2017开始,您可以使用STRING\u AGG(),但对于早期版本,XML方法是一种可行的方法 一些背景和提示 首先提示:您显示的代码对于XML特殊字符不安全。检查我下面的例子 首先,我

对于那些在SQLServer中使用JSON有经验的人来说,这可能是一个简单的问题。我在中发现了使用
FOR XML
聚合字符串的有趣方法


如何使用
JSON
而不是
XML
实现同样的功能

不能用JSON替代XML方法。这种字符串连接的工作原理是由于一些XML内部特性,这些特性在JSON中是不同的

从SQL Server 2017开始,您可以使用
STRING\u AGG()
,但对于早期版本,XML方法是一种可行的方法

一些背景和提示 首先提示:您显示的代码对于XML特殊字符不安全。检查我下面的例子

首先,我声明一个简单的XML

DECLARE  @xml XML=
N'<a>
  <b>1</b>
  <b>2</b>
  <b>3</b>
  <c>
    <d>x</d>
    <d>y</d>
    <d>z</d>
  </c>
</a>';
--可以指定获取123或xyz的路径

SELECT @xml.query('/a/b').value('.','varchar(100)')
SELECT @xml.query('//d').value('.','varchar(100)')
    
现在,您要解决的问题是连接表格数据:

DECLARE @tbl TABLE(SomeString VARCHAR(100));
INSERT INTO @tbl VALUES('This'),('will'),('concatenate'),('magically'),('Forbidden Characters & > <');
--但是我们可以不使用任何标签创建相同的内容:
--注意:仔细看,即使没有标记,结果也是XML类型的,看起来像SSMS中的超链接

SELECT SomeString AS [*] FROM @tbl FOR XML PATH('');
--现在我们可以在周围的查询中用作子选择。
--结果以字符串形式返回,不再是XML类型的。。。看那些被禁的魔咒

SELECT
 (SELECT SomeString FROM @tbl FOR XML PATH('row'))
,(SELECT SomeString AS [*] FROM @tbl FOR XML PATH(''))
--我们可以使用
,TYPE
强制将子选择视为XML类型本身
--这允许使用
.query()
和/或
.value()

XQuery的
.data()
可用于将命名元素与中间的空格连接起来。

XQuery的
.value()
必须用于重新生成禁止字符。

不能用JSON替换XML方法。这种字符串连接的工作原理是由于一些XML内部特性,这些特性在JSON中是不同的

从SQL Server 2017开始,您可以使用
STRING\u AGG()
,但对于早期版本,XML方法是一种可行的方法

一些背景和提示 首先提示:您显示的代码对于XML特殊字符不安全。检查我下面的例子

首先,我声明一个简单的XML

DECLARE  @xml XML=
N'<a>
  <b>1</b>
  <b>2</b>
  <b>3</b>
  <c>
    <d>x</d>
    <d>y</d>
    <d>z</d>
  </c>
</a>';
--可以指定获取123或xyz的路径

SELECT @xml.query('/a/b').value('.','varchar(100)')
SELECT @xml.query('//d').value('.','varchar(100)')
    
现在,您要解决的问题是连接表格数据:

DECLARE @tbl TABLE(SomeString VARCHAR(100));
INSERT INTO @tbl VALUES('This'),('will'),('concatenate'),('magically'),('Forbidden Characters & > <');
--但是我们可以不使用任何标签创建相同的内容:
--注意:仔细看,即使没有标记,结果也是XML类型的,看起来像SSMS中的超链接

SELECT SomeString AS [*] FROM @tbl FOR XML PATH('');
--现在我们可以在周围的查询中用作子选择。
--结果以字符串形式返回,不再是XML类型的。。。看那些被禁的魔咒

SELECT
 (SELECT SomeString FROM @tbl FOR XML PATH('row'))
,(SELECT SomeString AS [*] FROM @tbl FOR XML PATH(''))
--我们可以使用
,TYPE
强制将子选择视为XML类型本身
--这允许使用
.query()
和/或
.value()

XQuery的
.data()
可用于将命名元素与中间的空格连接起来。


XQuery的
.value()
必须用于重新设置禁止字符。

我很困惑。你为什么要这么做?如果您使用的是较新版本的SQL Server,那么请忘记这一点,使用
string\u agg()
。聚合字符串连接实际上应该是SQL中的一个基本函数。哦,等等。它在标准中,但SQL Server选择了另一个名称。在SQL Server 2017及更高版本中,请使用STRING_AGG。在以前的版本中,使用JSON并不比使用XML好多少。你为什么特别想要JSON?附言:这个有重复的already@GordonLinoff你能指出标准吗?(故意的双关语,知道你必须付费才能获得标准,但谁知道呢)@GordonLinoff基于它看来listag是所有数据库中一致性非常差的函数之一。这对我来说并不罕见SQL@GordonLinoff我正在使用2016。它没有STRING_AGG函数,但有JSON。我想知道哪一个性能更好,我想JSON就是答案。我很困惑。你为什么要这么做?如果您使用的是较新版本的SQL Server,那么请忘记这一点,使用
string\u agg()
。聚合字符串连接实际上应该是SQL中的一个基本函数。哦,等等。它在标准中,但SQL Server选择了另一个名称。在SQL Server 2017及更高版本中,请使用STRING_AGG。在以前的版本中,使用JSON并不比使用XML好多少。你为什么特别想要JSON?附言:这个有重复的already@GordonLinoff你能指出标准吗?(故意的双关语,知道你必须付费才能获得标准,但谁知道呢)@GordonLinoff基于它看来listag是所有数据库中一致性非常差的函数之一。这对我来说并不罕见SQL@GordonLinoff我正在使用2016。它没有STRING_AGG函数,但有JSON。我想知道哪一个性能更好,我想JSON就是答案。非常详细的解释,+1来自我这边!很好的解释。但是我很困惑,我的问题的答案是什么。因为你说我们不能用JSON做同样的事情,但是@GordonLinoff在上面的评论中说“你可以——毫无疑问——为JSON调整解决方案”。@Theesnssiavashi没有没有项目名称的JSON。剩下的将是丑陋的字符串操作……这是一个很好的解释,但是如果
SomeString
包含XML中无效的字符,它就不起作用了。
,TYPE
转换失败,出现错误。@GPHemsley在这种情况下,您可以使用
SomeString
包装为[*]作为xml路径(“”)
。这将隐式完成所有转义。非常详细的解释,+1来自我这边!很好的解释。但是我很困惑,我的问题的答案是什么。因为你说我们不能用JSON做同样的事情,但是@GordonLinoff在上面的评论中说“你可以——毫无疑问——为JSON调整解决方案”。@Theesnssiavashi没有没有项目名称的JSON。剩下的将是丑陋的字符串操作……这是一个很好的解释,但是如果
SomeString
包含XML中无效的字符,它就不起作用了。
,键入
转换