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