【问题标题】:Parse JSON structure in SQL在 SQL 中解析 JSON 结构
【发布时间】:2019-06-26 16:44:07
【问题描述】:

我已经编写了一个代码,可以将信息从 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] 对我来说真的不起作用。你对我有什么建议,我该如何改进这段代码?谢谢!

【问题讨论】:

    标签: sql json sql-server parsing sql-server-2016


    【解决方案1】:

    你可以使用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

    【讨论】:

    • 您好,感谢您的回答。但是,当我有两个考试数组时,它不能正常工作。 Your.code 只取第一个。你知道怎么解决吗?
    • @Lesley.H 您好,首先 SO 不是代码服务。下次请发布一个示例,展示您使用dbfiddle.uk 简化场景的真实示例,仅作为起点;)
    猜你喜欢
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    • 1970-01-01
    • 1970-01-01
    • 2019-06-24
    相关资源
    最近更新 更多