2016-05-28 1 views
5

Je souhaite obtenir JSON avec un tableau d'entiers utilisant la fonctionnalité For JSON de SQL Server 2016. Je suis perplexe sur le tableau des entiers.SQL Server 2016 pour le tableau d'entiers de sortie JSON

structures de table de base de données:

declare @Employees table (ID int, Name nvarchar(50)) 
insert into @Employees values 
(1, 'Bob'), 
(2, 'Randy') 

declare @Permissions table (ID int, PermissionName nvarchar(50)) 
insert into @Permissions values 
(1, 'Post'), 
(2, 'Comment'), 
(3, 'Edit'), 
(4, 'Delete') 

declare @EmployeePermissions table (EmployeeID int, PermissionID int) 
insert into @EmployeePermissions values 
(1, 1), 
(1, 2), 
(2, 1), 
(2, 2), 
(2, 3) 

résultats souhaités:

{"EmployeePermissions": [ 
    {"Employee":"Bob", "Permissions":[1,2]}, 
    {"Employee":"Randy", "Permissions":[1,2,3]} 
} 

C'est le plus proche que je suis devenu, mais pas tout à fait ce que je veux.

select 
    e.Name as Employee, 
    (select 
     convert(nvarchar(10),ep.PermissionID) as PermID 
    from @EmployeePermissions ep 
    where ep.EmployeeID=e.ID 
    for json path) as 'Permissions' 
from 
    @Employees e 
for json path, root('EmployeePermissions') 

retours:

{"EmployeePermissions": [ 
    {"Employee":"Bob", "Permissions":[{"permID":1},{"permID":2}]}, 
    {"Employee":"Randy", "Permissions":[{"permID":1},{"permID":2},{"permID":3}]} 
} 
+0

Pouvez-vous s'il vous plaît partager le code de travail, il sera contribue à donner plus de réponses – Arulkumar

+0

creat une vue/ResultSet en utilisant pour permID puis obtenir le résultat fait http://stackoverflow.com/questions/10461874/sql-server-concatenate-group-by –

+0

@Arulkumar - a ajouté mon code le plus proche. –

Répondre

2

Vous pouvez utiliser FOR XML PATH et STUFF pour faire PermissionID une virgule chaîne séparée pour chaque Employee, utilisez QUOTENANE dessus, puis mettre tous dans la variable et remplacer "[ avec [ et ]" avec ]:

DECLARE @json NVARCHAR(max) 

SELECT @json = REPLACE(REPLACE((
    SELECT e.Name as [Employee], 
      QUOTENAME(STUFF((SELECT ','+CAST(ep.PermissionID as nvarchar(10)) 
      FROM EmployeePermissions ep 
      WHERE e.ID = ep.EmployeeID 
      FOR XML PATH('')),1,1,'')) 
      as [Permissions] 
    FROM Employees e 
    FOR JSON AUTO, ROOT('EmployeePermissions') 
),'"[','['),']"',']') 

SELECT @json 

Sortie:

{"EmployeePermissions":[ 
    {"Employee":"Bob","Permissions":[1,2]}, 
    {"Employee":"Randy","Permissions":[1,2,3]} 
]} 

EDIT:

Une autre façon:

SELECT '{"EmployeePermissions":[' + STUFF((
SELECT ',{"Employee":"' + e.Name + '","Permissions":[' + 
     STUFF((SELECT ',' + CAST(PermissionID as nvarchar(10)) 
     FROM EmployeePermissions ep 
     WHERE ep.EmployeeID = e.ID 
     FOR XML PATH('')),1,1,'') +']}' 
FROM Employees e 
FOR XML PATH('')),1,1,'') + ']}' 

Sortie:

{"EmployeePermissions":[ 
    {"Employee":"Bob","Permissions":[1,2]}, 
    {"Employee":"Randy","Permissions":[1,2,3]} 
]} 
+0

Ferme, bien que je veuille un tableau de nombres, comme ceci:" Permissions ": [1,2,3] –

+0

Que diriez-vous de ceci (vérifiez la modification à ma réponse) – gofr1

+0

C'est la bonne sortie, mais je ne veux pas des techniques de concaténation strictement de corde. La partie de tableau peut utiliser des astuces de chaîne, mais la requête externe (qui est simplifiée dans ce cas) doit utiliser la fonctionnalité "Pour JSON". –

5

En AdventureWorks 2016 CTP3 exemple JSON vous pouvez trouver une fonction peut nettoyer tableau de clé: valeur pa irs et créer un tableau de valeurs: od

DROP FUNCTION IF EXISTS dbo.ufnToRawJsonArray 
GO 
CREATE FUNCTION 
[dbo].[ufnToRawJsonArray](@json nvarchar(max), @key nvarchar(400)) returns nvarchar(max) 
AS BEGIN 
     declare @new nvarchar(max) = replace(@json, CONCAT('},{"', @key,'":'),',') 
     return '[' + substring(@new, 1 + (LEN(@key)+5), LEN(@new) -2 - (LEN(@key)+5)) + ']' 
END 

juste de votre fournir des résultats SELECT FOR expression JSON comme paramètre @json et le nom de la clé que vous souhaitez supprimer en tant que second paramètre. Probablement quelque chose comme:

select 
e.Name as Employee, 
JSON_QUERY(dbo.ufnToRawJsonArray(
    (select 
    convert(nvarchar(10),ep.PermissionID) as PermID 
    from @EmployeePermissions ep 
    where ep.EmployeeID=e.ID 
    for json path) 
    , 'PermID')) 
    as 'Permissions' 
from 
@Employees e 
for json path, root('EmployeePermissions')