Как использовать метод OPENJSON с вложенным JSON, имеющим неопределенный/динамический путь?

#sql #json #open-json #json-value

Вопрос:

Я работаю с API, который выдает данные в виде динамического json, т. Е. Расположение некоторых элементов объектов json не фиксировано, это приводит к тому, что некоторые элементы в массивах json являются динамическими. Например, в объекте JSON под массивом «Свойство» в разделе может находиться под n-уровнем вложенности. Имеет ли OPENJSON какую-либо функцию поиска/поиска, которая может найти местоположение массива с именем «Свойство» и просто распечатать элементы в таблице?

Вот рабочая модель, но я должен использовать принудительный индекс (‘$.rows[2]’) для массива, чтобы показать желаемый результат. Однако массив свойств может находиться где угодно.

JSON

 Declare @Jsonobj as nvarchar(max) Select @Jsonobj = N'{  "ID": "StudentInformation",  "Name": "Student Information",  "Type": "s_info",  "Details": [  "Student Information",  "Greendale Community College"  ],  "Date": "21 October 2021",  "Rows": [  {  "RowType": "Header",  "Cells": [  {  "Value": ""  },  {  "Value": "21 Feb 2021"  },  {  "Value": "22 Aug 2020"  }  ]  },  {  "RowType": "Section",  "Title": "Class",  "Rows": []  },  {  "RowType": "Section",  "Title": "Grade",  "Rows": [  {  "RowType": "Row",  "Cells": [  {  "Value": "5A",  "Property": [  {  "Id": "1",  "Value": "John Smith"  }  ]  },  {  "Value": "5A",  "Property": [  {  "Id": "2",  "Value": "Jane Doe"  }  ]  },  {  "Value": "5B",  "Property": [  {  "Id": "1",  "Value": "Ben Frank"  }  ]  }  ]  }  ]  }  ] }'  

SQL

 SELECT JSON_VALUE(v.value, 'strict $.Value') as Names FROM OPENJSON(@Jsonobj, 'strict $.Rows[2].Rows') c CROSS APPLY OPENJSON(c.value, 'strict $.Cells') p CROSS APPLY OPENJSON(p.value, 'strict $.Property') v  

Ответ №1:

Вот что я нашел, что работает:

 SELECT d.value Names  FROM OPENJSON(@Jsonobj,'$.Rows')  WITH([Rows] NVARCHAR(MAX) AS JSON) A  OUTER APPLY OPENJSON(A.[Rows]) B  OUTER APPLY OPENJSON(B.[value],'$.Cells') C  OUTER APPLY OPENJSON(c.[value],'$.Property') WITH (Value NVARCHAR(MAX)) d  where d.value is not null