2016-06-08 1 views
12

SQL 2016 a une nouvelle fonctionnalité qui convertit les données sur le serveur SQL en JSON. J'éprouve des difficultés à combiner tableau d'objets dans un tableau de valeurs-à-dire,SQL vers JSON - tableau d'objets à un tableau de valeurs dans SQL 2016

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 que -

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

Quelqu'un peut-il m'aider s'il vous plaît?

+0

Je pense que cela pourrait être la façon dont cela fonctionne. [Vous remarquerez peut-être que FOR JSON renvoie un tableau de paires clé-valeur, même si nous souhaitons avoir quelque chose de plus simple, par ex. tableau clair de valeurs au lieu du tableau d'objets. Dans ce cas, nous pouvons écrire une simple fonction définie par l'utilisateur T-SQL qui supprime les clés du tableau et renvoie tableau simple:] (https://blogs.msdn.microsoft.com/sqlserverstorageengine/2015/10/09/returning-child- files-formatted-as-json-in-sql-server-queries /) –

Répondre

7

Merci! La soultion 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 
+0

Je pense qu'en raison du problème de performance de la requête FOR XML, ce n'est pas une bonne pratique –

5

Martin!

Je crois que c'est une encore plus simple façon de le faire:

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

C'est un bien meilleur hack que tout autre que j'ai vu. Et malheureusement, cela a atteint le [cimetière des demandes de fonctionnalités] (https://connect.microsoft.com/SQLServer/Feedback/Details/1383569). – harpo

+0

Eh bien, j'ai voté par un :-) –

0

Comme les tableaux de valeurs primitives sont valables JSON, il semble étrange qu'une installation pour sélectionner des tableaux de valeurs primitives ne se construit pas dans SQL La fonctionnalité JSON du serveur. (Si au contraire une telle fonctionnalité existe, je n'ai au moins pas pu la découvrir après un peu 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 ex, 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''), '"}',''); 

œuvres de production:

"Children": ["101026,"101027] 

Mais, suivant l'approche ci-dessus, celle-ci:

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\"]" 
    } 
] 

Lorsque le tableau Children est encapsulé sous forme de chaîne.

+0

Ajouter JSON_QUERY() autour de remplacer. Cela va désactiver l'échappement redondant – DiGi

1

La plupart de ces solutions créent essentiellement un fichier CSV qui représente le contenu du tableau, puis le place dans le 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 
2
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 

Quand on veut concaténer des chaînes comme tableau JSON alors:

1) chaîne d'échappement - STRING_ESCAPE

2) chaîne concatenate par des virgules séparateur - STRING_AGG, code ASCII ASCII est 44

3) Ajouter une citation entre parenthèses - QUOTENAME (sans param)

4) retourner la chaîne (avec un tableau d'éléments) comme json - JSON_QUERY

+0

STRING_AGG n'est pas disponible dans SQL 2016? – TaylorN