Разобрать структуру JSON в SQL - PullRequest
1 голос
/ 26 июня 2019

Я написал код, который считывает информацию из строк JSON в таблицу в 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]

Код работает нормально, но я действительно ненавижу N'$.Attributes[2].Value' часть.Информация об экзамене может быть на первом, втором, третьем месте, поэтому [2] на самом деле не работает для меня.Есть ли у вас какие-либо предложения для меня, как я могу улучшить этот код?Спасибо!

1 Ответ

1 голос
/ 26 июня 2019

Вы можете использовать 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


РЕДАКТИРОВАТЬ:

В исходном вопросе был только один экзамен в массиве.Если массив может содержать больше, чем код, необходимо откорректировать:

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

...