Here is my problem: My JSON may vary based on API response and there is no guarantee that “shortTitle”, for example, can be present in my JSON next time when there is a post request. I have to figure how to “loop” (if that’s the correct term) through JSON to get all fieldID and contents without losing any data.
Here is the query:
DECLARE // hardcoded json to simulate a post request @json nvarchar(max) = '{ "itemTypeID": 13, "authorRights": { "fieldID": 15, "content": "abcd" }, "language": { "fieldID": 7, "content": "abcd" }, "url": { "fieldID": 13, "content": "abcd" }, "shortTitle": { "fieldID": 8, "content": "abcd" }, "data": { "fieldID": 6, "content": "2022-03-02" }, "summary": { "fieldID": 2, "content": "abcd" }, "subject": { "fieldID": 60, "content": "abcd" } }'; BEGIN SELECT* FROM OPENJSON(@json) WITH( fieldID bigint '$.data.fieldID', content nvarchar(255) '$.data.content' ) END;
This query returns fieldID and content only for “data” (results). How can I return fieldID and content for all objects?
Advertisement
Answer
If I understand the structure of the input JSON correctly, you need to parse only nested JSON objects. So, using OPENJSON()
with default schema and an additional APPLY
operator is a possible solution to your problem. As is explained in the documentation, the OPENJSON()
function with default schema returns a table with columns key
, value
and type
, and the type
column holds an int value that contains the type of the returned value.
SELECT j1.[key], j2.fieldID FROM OPENJSON(@json) j1 CROSS APPLY OPENJSON (j1.[value]) WITH (fieldID bigint '$.fieldID') j2 WHERE j1.[type] = 5
Result:
key fieldID --------------------- authorRights 15 language 7 url 13 shortTitle 8 data 6 summary 2 subject 60