SQL 2016 a une nouvelle fonctionnalité qui convertit les données du serveur SQL en JSON. J'ai du mal à combiner un tableau d'objets dans un tableau de valeurs, c'est-à-dire
EXEMPLE -
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'))
RÉSULTAT -
{
"ids": [{
"item_id": "1234"
},
{
"item_id": "5678"
},
{
"item_id": "7890"
}]
}
Mais je veux que le résultat soit -
"ids": [
"1234",
"5678",
"7890"
]
Quelqu'un peut-il m'aider?
Merci! L'âme que nous avons trouvée convertit d'abord en XML -
SELECT
JSON_QUERY('[' + STUFF(( SELECT ',' + '"' + item_id + '"'
FROM #temp FOR XML PATH('')),1,1,'') + ']' ) ids
FOR JSON PATH , WITHOUT_ARRAY_WRAPPER
Martin!
Je pense que c'est une façon encore plus simple de le faire:
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
Lorsque nous voulons concaténer des chaînes en tant que tableau json, alors:
1) chaîne d'échappement - STRING_ESCAPE
2) concaténer une chaîne avec un séparateur de virgules - STRING_AGG, le code ascii de la virgule est 44
3) ajouter la citation entre parenthèses - QUOTENAME (sans param)
4) retourne la chaîne (avec un tableau d'éléments) en json - JSON_QUERY
Étant donné que les tableaux de valeurs primitives sont des JSON valides, il semble étrange qu'une fonction de sélection de tableaux de valeurs primitives ne soit pas intégrée dans la fonctionnalité JSON de SQL Server. (Si au contraire une telle fonctionnalité existe, je n'ai au moins pas pu la découvrir après pas mal de recherche).
L'approche décrite ci-dessus fonctionne comme décrit. Mais lorsqu'il est appliqué pour un champ dans une requête plus grande, le tableau de primitives est entouré de guillemets.
Par exemple, ce
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''), '"}','');
fonctionne en produisant:
"Children": ["101026,"101027]
Mais, en suivant l'approche ci-dessus, ceci:
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
Produit:
[
{
"PartNumber": "104444",
"Description": "ASSY HUB R-SER DRIV HP10 ABS",
"Children": "[\"101026\",\"101027\",\"102291\",\"103430\",\"103705\",\"104103\"]"
}
]
Où le tableau Enfants est encapsulé sous forme de chaîne.
La plupart de ces solutions créent essentiellement un CSV qui représente le contenu du tableau, puis mettent ce CSV au format JSON final. Voici ce que j'utilise pour éviter 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