简体   繁体   中英

Parse JSON structure in SQL

I have written a code that reads information from JSON lines to table in SQL:

declare @pJSON varchar(max) = '
{
    "School": "MiddleSchool",
    "Password": "SchoolPassword",
    "Attributes": [
        {
            "Type": "Exam",
            "Value": "1"
        },
        {
            "Type": "Class",
            "Value": "11b"
        },
        {
            "Type": "Math",
            "Value": [
               {
                    "ExamDate": "2019-01-01",
                    "Points": 100,
                    "Grade": 10,
                    "Notes": "Good"
                }
            ]
        }   
    ]   
}   '


select ExamDate, Points, Grade, Notes   
from OPENJSON(@pJSON, N'$.Attributes[2].Value')    
cross apply openjson ([Value])   
with    
(    
  ExamDate date,    
  Points int,    
  Grade int,    
  Notes varchar(max)    
) as [value]

Code works fine, but I really hate N'$.Attributes[2].Value' part. Exam information can be in the first, second, third place, so [2] doesn't really work for me. Do you have any suggestions for me, how I can improve this code? Thank you!

You could use JSON_QUERY :

select ExamDate, Points, Grade, Notes   
from OPENJSON(JSON_QUERY(@pJSON, N'$.Attributes'))
with    
(    
  ExamDate date      N'$.Value[0].ExamDate',  -- here 0 because Value is array too
  Points int         N'$.Value[0].Points',    
  Grade int          N'$.Value[0].Grade',    
  Notes varchar(max) N'$.Value[0].Notes'
) as [value]
WHERE ExamDate IS NOT NULL;

db<>fiddle demo


EDIT:

In original question there was only one exam in array. If array could contain more than code should be adjusted:

SELECT s2.[key]
      ,ExamValue = JSON_VALUE(s2.value, '$.ExamDate')
      ,Points    = JSON_VALUE(s2.value, '$.Points')
      ,Grade     = JSON_VALUE(s2.value, '$.Grade')
      ,Notes     = JSON_VALUE(s2.value, '$.Notes')
FROM OPENJSON(JSON_QUERY(@pJSON, N'$.Attributes')) s
CROSS APPLY OPENJSON(JSON_QUERY(s.value, N'$.Value')) s2;

-- or
SELECT [value].*
FROM OPENJSON(JSON_QUERY(@pJSON, N'$.Attributes'))
CROSS APPLY OPENJSON(JSON_QUERY(value, N'$.Value'))
with    
(    
  ExamDate date      N'$.ExamDate', 
  Points int         N'$.Points',    
  Grade int          N'$.Grade',    
  Notes varchar(max) N'$.Notes'
) as [value];

db<>fiddle demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM