SQL到JSON-SQL 2016中对象数组到值数组

SQL到JSON-SQL 2016中对象数组到值数组,sql,json,sql-server-2016,Sql,Json,Sql Server 2016,SQL 2016具有将SQL server上的数据转换为JSON的新功能。我难以将对象数组组合成值数组,即 示例- CREATE TABLE #temp (item_id VARCHAR(256)) INSERT INTO #temp VALUES ('1234'),('5678'),('7890') SELECT * FROM #temp --convert to JSON SELECT (SELECT item_id FROM #temp FOR JSON PATH,root('i

SQL 2016具有将SQL server上的数据转换为JSON的新功能。我难以将对象数组组合成值数组,即

示例-

CREATE TABLE #temp (item_id VARCHAR(256))

INSERT INTO #temp VALUES ('1234'),('5678'),('7890')

SELECT * FROM #temp

--convert to JSON

SELECT (SELECT item_id 
FROM #temp
FOR JSON PATH,root('ids')) 
结果-

{
    "ids": [{
        "item_id": "1234"
    },
    {
        "item_id": "5678"
    },
    {
        "item_id": "7890"
    }]
}
但我希望结果是-

"ids": [
        "1234",
        "5678",
        "7890"
    ]

谁能帮帮我吗?

谢谢!我们找到的解决方案正在首先转换为XML-

SELECT  
JSON_QUERY('[' + STUFF(( SELECT ',' + '"' + item_id + '"' 
FROM #temp FOR XML PATH('')),1,1,'') + ']' ) ids  
FOR JSON PATH , WITHOUT_ARRAY_WRAPPER 
马丁

我相信这是一种更简单的方法:

    SELECT '"ids": ' + 
    REPLACE( 
      REPLACE( (SELECT item_id FROM #temp FOR JSON AUTO),'{"item_id":','' ),
      '"}','"' )

由于原语值数组是有效的JSON,因此SQL Server的JSON功能中没有内置用于选择原语值数组的功能,这似乎很奇怪。如果相反,这样的功能存在的话,我至少在经过一段时间的搜索之后还没有发现它

上述方法的工作原理如前所述。但是当应用于较大查询中的字段时,原语数组被引号包围

例如,这个

DECLARE @BomTable TABLE (ChildNumber dbo.udt_ConMetPartNumber);
INSERT INTO @BomTable (ChildNumber) VALUES (N'101026'), (N'101027');
SELECT N'"Children": ' + REPLACE(REPLACE((SELECT ChildNumber FROM @BomTable FOR JSON PATH), N'{"ChildNumber":', N''), '"}','');
制作作品:

"Children": ["101026,"101027]
但是,按照上述方法,这:

SELECT
    p.PartNumber,
    p.Description,
    REPLACE(REPLACE((SELECT
                        ChildNumber
                     FROM
                        Part.BillOfMaterials
                     WHERE
                        ParentNumber = p.PartNumber
                     ORDER BY
                        ChildNumber
                    FOR
                     JSON AUTO
                    ), N'{"ChildNumber":', N''), '"}', '"') AS [Children]
FROM
    Part.Parts AS p
WHERE
    p.PartNumber = N'104444'
FOR
    JSON PATH
产生:

[
    {
        "PartNumber": "104444",
        "Description": "ASSY HUB           R-SER  DRIV HP10  ABS",
        "Children": "[\"101026\",\"101027\",\"102291\",\"103430\",\"103705\",\"104103\"]"
    }
]

其中子数组被包装为字符串。

大多数解决方案基本上都是创建一个表示数组内容的CSV,然后将该CSV转换为最终的JSON格式。为了避免使用XML,我使用以下方法:

DECLARE @tmp NVARCHAR(MAX) = ''

SELECT @tmp = @tmp + '"' + [item_id] + '",'
FROM #temp -- Defined and populated in the original question

SELECT [ids] = JSON_QUERY((
    SELECT CASE
        WHEN @tmp IS NULL THEN '[]'
        ELSE '[' + SUBSTRING(@tmp, 0, LEN(@tmp)) + ']'
        END
    ))
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
当我们想将字符串连接为json数组时,那么:

转义字符串-字符串\u转义

用逗号分隔符连接字符串-字符串_AGG,逗号ascii码为44

在括号中添加引号-QUOTENAME,不带参数

返回包含json-json\u查询元素数组的字符串


此版本基于其他版本:

正确转义特殊的JSON字符,例如引号 不返回任何数据的空数组[] 由于字符串_AGG,需要SQL 2017或更高版本:

选择 CONCAT'[', 选择字符串+字符串+转义项id,'json'+'',' 临时工 , ']'
我想这可能就是它的工作方式。这是一个严重的障碍,因为JSON没有指定“数组路径”的方法,这将使这种转换变得微不足道,而不需要手动构建字符串:既可以为元组指定索引,也可以为构建长度不确定的嵌套数组指定“last”。也许在2029年JSON生成中如此明显的遗漏是正确的?sighI认为由于FOR XML查询的性能问题,这不是一个好的做法。我们可以使用string_escapeitem_id,N'json来避免产生无效的json格式。我已经使用这个格式很长时间了。SQL server 2016是否有一个较短的版本?这是一个比我见过的任何其他版本都好得多的黑客攻击。不幸的是,这已经到达了关于REPLACE的.addjson_查询。这将禁用SQL 2016中不可用的冗余转义字符串?如果您运行的是最新版本的SQL Server,这是最干净的解决方案。为什么将char44用作逗号而不是文字“,”?虽然这是最干净的解决方案,但此处的quotename函数是错误的。它不仅在值周围添加括号,而且根据SQL转义规则(而不是JSON)在值内部转义闭括号[]。因此,如果@temp中的字符串值包含一个右括号,它将被错误地转义。正确的方法是“['+string_agg…+']”。注意:对于QUOTENAME函数,大于128个字符的输入返回NULL。从temp选择$tmp=$tmp+'+[item_id]+',不是连接字符串的正确方法。不能保证产生正确的结果。不得不将@替换为$commentCorrection:由于字符串_AGG,这需要SQL 2017或更高版本。
declare @temp table (item_id VARCHAR(256))

INSERT INTO @temp VALUES ('1234'),('5678'),('7890')

SELECT * FROM @temp

--convert to JSON

select 
    json_query(QUOTENAME(STRING_AGG('"' + STRING_ESCAPE(item_id, 'json') + '"', char(44)))) as [json]
from @temp
for json path