JSON SQL Server 2016 解析

Posted

技术标签:

【中文标题】JSON SQL Server 2016 解析【英文标题】:JSON SQL Server 2016 parse 【发布时间】:2019-12-22 17:52:15 【问题描述】:

我有一个嵌套的 JSON 作为表单的输出,我需要解析它以便将它发送到连接表中。我无法解析 JSON 中的一些数据:标签、范围值或正文我得到 NULL 有人遇到过这种类型的吗?

    DECLARE @json NVARCHAR(MAX)
SET @json = '
   "Id":"712db489",
   "label":"kjk",
   "ranges":
      "rangeQuestion":null,
      "minRange":0,
      "maxRange":10,
      "rangeValues":[1,2],
      "hasMarks":false
   ,
   "labels":[1,2],
   "options":[
      
         "body":"Yes",
         "sequence":1
      ,
      
         "body":"No",
         "sequence":2
      
   ]
'

SELECT * FROM  
 OPENJSON ( @json )  
WITH (   
              label   nvarchar(250), --ok
              maxRange   nvarchar(250) '$.ranges.maxRange', --ok
              labels   nvarchar(250), -- not parsed
              rangesValues nvarchar(250) '$.ranges.rangeValues' , -- not parsed
              body   nvarchar(250) '$.options.body' -- not parsed

 ) 

输出应该是这样的

minRange maxRange rangeValues 0 10 1 0 10 2

身体顺序

是的 1

没有 2

如果嵌套了 3 个级别,可以做什么?

DECLARE @json NVARCHAR(MAX)

SET @json = '
   "Id":"712db489",
   "label":"kjk",
   "ranges":
      "rangeQuestion":null,
      "minRange":0,
      "maxRange":10,
      "rangeValues": [
                
                    "rangeValue": 1,
                    "otherValue": 10
                ,
                
                    "rangeValue": 2,
                    "otherValue": 20
                
            ],
      "hasMarks":false
   ,
   "labels":[1,2],
   "options":[
      
         "body":"Yes",
         "sequence":1
      ,
      
         "body":"No",
         "sequence":2
      
   ]
'

SELECT r.minRange,
       r.maxRange,
       rV.[value] AS rangeValue
FROM OPENJSON (@json, '$.ranges')  
     WITH (minRange int,
           maxRange int,
           rangeValues nvarchar(MAX) 
           AS JSON) r
     CROSS APPLY OPENJSON (r.rangeValues) rV;

【问题讨论】:

您在期待什么? $.ranges.maxRange 中有一个数组值,例如 [1,2]。您是否期待数组,12 或 2 行(具有值 12)?其他“失败”的也一样。请务必向我们展示您所追求的预期结果。 maxRange 返回正常,但是标签因为我混合了数组为 [1,2] 以及其他对象(如选项),我需要将它们放在单独的行中 minRange maxRange rangeValues 0 10 1 0 10 2 身体序列 是 1 否 2 向我们展示您期望的结果。例如,1 是否与 YesNo 相关? 在选项1的情况下与yes有关,而2与no有关 所以你想要 2 个数据集?当您尝试使用label 时,为什么两者都没有? 【参考方案1】:

看起来,从 cmets 的讨论来看,你真正想要的是:

SELECT r.minRange,
       r.maxRange,
       rV.[value] AS rangeValue
FROM OPENJSON (@json, '$.ranges')  
     WITH (minRange int,
           maxRange int,
           rangeValues nvarchar(MAX) AS JSON) r
     CROSS APPLY OPENJSON (r.rangeValues) rV;

SELECT *
FROM OPENJSON (@json,'$.options')
     WITH (body varchar(3),
           sequence int) o;

【讨论】:

它有效!我在一些例子中看到了十字架适用,但我没有使用它。谢谢 当我有 3 个嵌套级别时,如何将值提取到最后一层?不同的是它不是数组而是第三层的对象 听起来你应该问另一个问题,@drcz。【参考方案2】:

我解决的第二个问题

DECLARE @json NVARCHAR(MAX)

SET @json = '
   "Id":"712db489",
   "label":"kjk",
   "ranges":
      "rangeQuestion":null,
      "minRange":0,
      "maxRange":10,
      "rangeValues": [
                
                    "rangeValue": 1,
                    "otherValue": 10
                ,
                
                    "rangeValue": 2,
                    "otherValue": 20
                
            ],
      "hasMarks":false
   ,
   "labels":[1,2],
   "options":[
      
         "body":"Yes",
         "sequence":1
      ,
      
         "body":"No",
         "sequence":2
      
   ]
'

SELECT ranges.minRange as minRange,
       ranges.maxRange as maxRange,
       rangeValues.rangeValue AS rangeValue
FROM OPENJSON (@json, '$.ranges')  
WITH (minRange int,
    maxRange int,
    rangeValues nvarchar(MAX) AS JSON
    ) as ranges
CROSS APPLY OPENJSON (ranges.rangeValues) 
with (
rangeValue int ,
otherValue int
)as rangeValues;

【讨论】:

以上是关于JSON SQL Server 2016 解析的主要内容,如果未能解决你的问题,请参考以下文章