Je suis actuellement en mesure d'analyser la plupart des fichiers JSON à l'aide de la syntaxe "OPENJSON WITH (...") de SQL Server. Toutefois, ce fichier contient des tableaux imbriqués que je ne sais pas comment gérer.
La plupart des exemples que j'ai lus font référence à JSON en tant que variable. Dans ce cas, j'appelle un fichier:
select DEV_JSON.*
from OPENROWSET
(BULK 'C:\Users\Myuser\Documents\JSON_extract.json', SINGLE_CLOB) as my_datafile
CROSS APPLY OPENJSON(BulkColumn)
WITH
(DOC_ID varchar(100) '$.doc._id',
DOC_REV varchar(45) '$.doc._rev',
DELY_APPL_NAME varchar(20) '$.doc.delivery.application',
DELY_SENT_BY varchar(25) '$.doc.delivery.sender.id',
DELY_SENT_TYPO varchar(20) '$.doc.delivery.sender.type',
.....
....
...
..) as DEV_JSON
L'un des attributs contient un tableau imbriqué. Ci-dessous, j'ai copié les 5 premiers attributs de mon JSON, ainsi que le tableau "destinataires" imbriqué.
Comment structurer mon SQL pour analyser cette section?
"doc": {
"_id": "[email protected]",
"_rev": "3-e119db13dae8d50ae0c4579ba9c87fc9",
"delivery": {
"application": "App_XYZ",
"sender": {
"id": "[email protected]",
"type": "user"
},
"recipients": [{
"type": "email",
"recipient": "\"Artzer, Daniel J\" <[email protected]>",
"sentTS": "2017-10-18T13:04:00.133Z"
},
{
"type": "email",
"recipient": "\"Higgins, Laura L\" <[email protected]>",
"sentTS": "2017-10-18T13:04:00.133Z"
},
{
"type": "email",
"recipient": "\"Friedman, Brian\" <[email protected]>",
"sentTS": "2017-10-18T13:04:00.133Z"
},
{
"type": "email",
"recipient": "\"Garcia, Charlie M\" <[email protected]>",
"sentTS": "2017-10-18T13:04:00.133Z"
}
]
},
Je viens d'avoir le même problème et j'ai fini par le résoudre avec plusieurs clauses CROSS APPLY.
Voici un exemple de mon JSON:
DECLARE @PermsJSON NVARCHAR(MAX) =
N'[{
"AppId": 1,
"Perms":
[{
"Permission": ["AA", "BB"],
"PermissionTypeID": 2
},
{
"Permission": ["10"],
"PermissionTypeID": 1
}]
},
{
"AppId": 2,
"Perms":
[{
"Permission": ["IM", "NM"],
"PermissionTypeID": 2
},
{
"Permission": ["42"],
"PermissionTypeID": 1
}]
}]';
Et puis je peux l'analyser en utilisant la requête suivante:
SELECT
a.AppId
,[Permission] = c.Value
,b.PermissionTypeID
FROM
OPENJSON(@PermsJSON)
WITH
(
AppId INT N'$.AppId'
,Perms NVARCHAR(MAX) AS JSON
) AS a
CROSS APPLY
OPENJSON(a.Perms)
WITH
(
PermissionTypeID INT
,[Permission] NVARCHAR(MAX) AS JSON
) AS b
CROSS APPLY OPENJSON(b.Permission) AS c;
Les résultats ressemblent alors à ceci:
AppId Permission PermissionTypeID
1 AA 2
1 BB 2
1 10 1
2 IM 2
2 NM 2
2 42 1
Après BEAUCOUP recherches, j'ai finalement découvert la réponse à ce problème. Je dois simplement inclure le tableau imbriqué comme une autre colonne JSON dans ma requête, comme ceci:
WITH
(DOC_ID varchar(100) '$.doc._id',
DOC_REV varchar(45) '$.doc._rev',
DELY_APPL_NAME varchar(20) '$.doc.delivery.application',
DELY_SENT_BY varchar(25) '$.doc.delivery.sender.id',
DELY_SENT_TYPO varchar(20) '$.doc.delivery.sender.type',
RECIPS nvarchar(max) '$.doc.delivery.recipients' as JSON,
PAYLOAD_START_TIME varchar(30) '$.doc.payload.startTS',
....
...
..
) as my_query
Je me retrouve donc avec un enregistrement par document JSON, avec (dans ce cas) une colonne varchar contenant du texte JSON.
Ensuite, je peux exécuter une requête distincte sur cette colonne pour analyser le JSON et créer une "table enfant" associée au parent.