如何使SQL生成的JSON中Customers数组的每个客户编号被引号包裹?
解决SQL生成JSON时客户编号数组元素带引号的问题
你的问题出在用STRING_AGG拼接成纯文本字符串后直接用JSON_ARRAY包装——这会把整个拼接后的字符串当成数组的单个元素,而且无法自动为每个客户编号添加引号(如果是数字类型还会被识别为JSON数字)。下面提供两种可靠的解决方案:
方案1:手动拼接带引号的JSON数组(简洁版)
通过STRING_AGG为每个客户编号添加引号,拼接成合法的JSON数组格式后,用JSON_QUERY让SQL Server识别为JSON类型:
SELECT LTRIM(RTRIM([Name])) AS [Name], LTRIM(RTRIM([Identifier])) AS Identifier, -- 为每个客户编号添加引号,转义内部双引号,拼接成JSON数组格式 JSON_QUERY('["' + STRING_AGG(REPLACE(LTRIM(RTRIM(custnmbr)), '"', '""'), '","') + '"]') AS Customers FROM [dbo].[AcctReps] GROUP BY [Identifier], [Name] FOR JSON AUTO, Root('Reps')
说明:
REPLACE(..., '"', '""'):避免客户编号中包含的双引号破坏JSON格式,自动转义为JSON兼容的双引号。JSON_QUERY:告诉SQL Server这个拼接后的字符串是合法JSON,不会再额外添加外层引号。
方案2:嵌套查询生成JSON数组(安全版)
利用FOR JSON PATH自动生成带引号的数组元素,无需手动处理转义,适合客户编号可能包含特殊字符的场景:
SELECT ar.[Name], ar.[Identifier], JSON_QUERY(( -- 子查询为当前Rep生成所有客户编号的JSON数组元素 SELECT LTRIM(RTRIM(sub.custnmbr)) AS [*] FROM [dbo].[AcctReps] sub WHERE sub.[Identifier] = ar.[Identifier] AND sub.[Name] = ar.[Name] FOR JSON PATH )) AS Customers FROM ( -- 先获取去重的Rep信息 SELECT DISTINCT LTRIM(RTRIM([Name])) AS [Name], LTRIM(RTRIM([Identifier])) AS Identifier FROM [dbo].[AcctReps] ) ar FOR JSON AUTO, Root('Reps')
说明:
- 子查询中
AS [*]:指定将查询结果作为JSON数组的直接元素,而非键值对。 FOR JSON PATH:自动生成格式正确的JSON数组,每个客户编号都会被包裹在双引号中,同时自动处理特殊字符转义。
两种方案最终生成的JSON结构示例:
{ "Reps": [ { "Name": "张三", "Identifier": "REP001", "Customers": ["CUST001", "CUST002"] } ] }
内容的提问来源于stack exchange,提问作者SteveG
相关产品推荐
相关产品推荐

