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 解析的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 2016 JSON原生支持实例说明

SQL Server OPENJSON 读取嵌套的 json

SQL Server JSON 数组

解析 JSON 文件并将数据插入 SQL Server

SQL SERVER解析Json

解析 JSON 数据并插入到 SQL Server 中的多个表中