type tipo openjson name manejo invalid campo json parsing hierarchy sql-server-2016 open-json

tipo - sql server type json



SQL Server OPENJSON leer json anidado (3)

Tengo algunos json que me gustaría analizar en SQL Server 2016. Hay una estructura de jerarquía de Proyectos-> Estructuras-> Propiedades. Me gustaría escribir una consulta que analice toda la jerarquía pero no quiero especificar ningún elemento por número de índice, es decir, no quiero hacer nada como esto:

openjson (@json, ''$[0]'')

o

openjson (@json, ''$.structures[0]'')

Tuve la idea de que podía leer los valores de los objetos de proyecto de nivel superior junto con la cadena json que representa las estructuras debajo de él, que luego podrían analizarse por separado. El problema es que el siguiente código no funciona:

declare @json nvarchar(max) set @json = '' [ { "IdProject":"97A76363-095D-4FAB-940E-9ED2722DBC47", "Name":"Test Project", "structures":[ { "IdStructure":"CB0466F9-662F-412B-956A-7D164B5D358F", "IdProject":"97A76363-095D-4FAB-940E-9ED2722DBC47", "Name":"Test Structure", "BaseStructure":"Base Structure", "DatabaseSchema":"dbo", "properties":[ { "IdProperty":"618DC40B-4D04-4BF8-B1E6-12E13DDE86F4", "IdStructure":"CB0466F9-662F-412B-956A-7D164B5D358F", "Name":"Test Property 2", "DataType":1, "Precision":0, "Scale":0, "IsNullable":false, "ObjectName":"Test Object", "DefaultType":1, "DefaultValue":"" }, { "IdProperty":"FFF433EC-0BB5-41CD-8A71-B5F09B97C5FC", "IdStructure":"CB0466F9-662F-412B-956A-7D164B5D358F", "Name":"Test Property 1", "DataType":1, "Precision":0, "Scale":0, "IsNullable":false, "ObjectName":"Test Object", "DefaultType":1, "DefaultValue":"" } ] } ] } ]''; select IdProject, Name, structures from openjson (@json) with ( IdProject uniqueidentifier, Name nvarchar(100), structures nvarchar(max) ) as Projects

No se devolvió ningún problema a IdProject y Name, pero por alguna razón no puedo mantener el json anidado en "estructuras". En lugar del contenido json, simplemente devuelve NULL:

¿Alguien sabe si esto es posible y, de ser así, qué hago mal?


¡Típico! Encontré la respuesta justo después de publicar la pregunta. Debe usar la palabra clave ''como json'' cuando especifique las columnas para devolver:

select IdProject, Name, structures from openjson (@json) with ( IdProject uniqueidentifier, Name nvarchar(100), structures nvarchar(max) as json ) as Projects


Si hace referencia a la matriz o al objeto JSON, debe especificar la cláusula AS JSON:

select IdProject, Name, structures from openjson (@json) with ( IdProject uniqueidentifier, Name nvarchar(100), structures nvarchar(max) AS JSON ) as Projects

Consulte las preguntas frecuentes: https://msdn.microsoft.com/en-us/library/mt631706.aspx#Anchor_6

Si desea aplicar OPENJSON en la matriz de estructuras devueltas, puede usar algo como el siguiente código:

select IdProject, Name, structures from openjson (@json) with ( IdProject uniqueidentifier, Name nvarchar(100), structures nvarchar(max) AS JSON ) as Projects CROSS APPLY OPENJSON (structures) WITH (......)


Utilizando CROSS APLICAR:

declare @json nvarchar(max) set @json = '' [ { "IdProject":"97A76363-095D-4FAB-940E-9ED2722DBC47", "Name":"Test Project", "structures":[ { "IdStructure":"CB0466F9-662F-412B-956A-7D164B5D358F", "IdProject":"97A76363-095D-4FAB-940E-9ED2722DBC47", "Name":"Test Structure", "BaseStructure":"Base Structure", "DatabaseSchema":"dbo", "properties":[ { "IdProperty":"618DC40B-4D04-4BF8-B1E6-12E13DDE86F4", "IdStructure":"CB0466F9-662F-412B-956A-7D164B5D358F", "Name":"Test Property 2", "DataType":1, "Precision":0, "Scale":0, "IsNullable":false, "ObjectName":"Test Object", "DefaultType":1, "DefaultValue":"" }, { "IdProperty":"FFF433EC-0BB5-41CD-8A71-B5F09B97C5FC", "IdStructure":"CB0466F9-662F-412B-956A-7D164B5D358F", "Name":"Test Property 1", "DataType":1, "Precision":0, "Scale":0, "IsNullable":false, "ObjectName":"Test Object", "DefaultType":1, "DefaultValue":"" } ] } ] } ]''; select Projects.IdProject, Projects.Name as NameProject, Structures.IdStructure, Structures.Name as NameStructure, Structures.BaseStructure, Structures.DatabaseSchema, Properties.* from openjson (@json) with ( IdProject uniqueidentifier, Name nvarchar(100), structures nvarchar(max) as json ) as Projects cross apply openjson (Projects.structures) with ( IdStructure uniqueidentifier, Name nvarchar(100), BaseStructure nvarchar(100), DatabaseSchema sysname, properties nvarchar(max) as json ) as Structures cross apply openjson (Structures.properties) with ( IdProperty uniqueidentifier, NamePreoperty nvarchar(100) ''$.Name'', DataType int, [Precision] int, [Scale] int, IsNullable bit, ObjectName nvarchar(100), DefaultType int, DefaultValue nvarchar(100) ) as Properties