SQL to JSON-массив объектов в массив значений в SQL 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('ids')) 

результат -

{
    "ids": [{
        "item_id": "1234"
    },
    {
        "item_id": "5678"
    },
    {
        "item_id": "7890"
    }]
}

но я хочу результат как -

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

кто-нибудь может мне помочь?

5 ответов


спасибо! В soultion мы нашли превращается в первую 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":','' ),
      '"}','"' )

declare @temp table (item_id VARCHAR(256))

INSERT INTO @temp VALUES ('123"4'),('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

когда мы хотим объединить строки как массив json, то:

1) escape string-STRING_ESCAPE

2) объединить строку с разделителем запятых-STRING_AGG, код ascii запятая 44

3) добавить цитату в скобках-QUOTENAME (без param)

4) возвращаемая строка (с массивом элементов) как json - JSON_QUERY


поскольку массивы примитивных значений являются допустимыми JSON, кажется странным, что средство выбора массивов примитивных значений не встроено в функциональность JSON SQL Server. (Если, наоборот, такая функциональность существует, я, по крайней мере, не смог ее обнаружить после довольно долгого поиска).

подход, описанный выше, работает, как описано. Но при применении к полю в большем запросе массив примитивов окружен кавычками.

Е. Г., это

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