2016-11-07 56 views
2

我有一个JSON结构,其中有部分,由多个渲染,它由多个字段组成。你怎么打开阵列的数组

如何在最低级别(字段)上执行1个OPENJSON调用以从中获取所有信息?

下面是一个例子JSON:

Declare @layout NVARCHAR(MAX) = N' 
    { 
     "Sections": [ 
      { 
       "SectionName":"Section1", 
       "SectionOrder":1, 
       "Renders":[ 
        { 
         "RenderName":"Render1", 
         "RenderOrder":1, 
         "Fields":[ 
          { 
           "FieldName":"Field1", 
           "FieldData":"Data1" 
          }, 
          { 
           "FieldName":"Field2", 
           "FieldData":"Data2" 
          } 
         ] 
        }, 
        { 
         "RenderName":"Render2", 
         "RenderOrder":2, 
         "Fields":[ 
          { 
           "FieldName":"Field1", 
           "FieldData":"Data1" 
          }, 
          { 
           "FieldName":"Field2", 
           "FieldData":"Data2" 
          } 
         ] 
        } 
       ] 
      }, 
      { 
       "SectionName":"Section2", 
       "SectionOrder":2, 
       "Renders":[ 
        { 
         "RenderName":"Render1", 
         "RenderOrder":1, 
         "Fields":[ 
          { 
           "FieldName":"Field1", 
           "FieldData":"Data1" 
          } 
         ] 
        }, 
        { 
         "RenderName":"Render2", 
         "RenderOrder":2, 
         "Fields":[ 
          { 
           "FieldName":"Field1", 
           "FieldData":"Data1" 
          }, 
          { 
           "FieldName":"Field2", 
           "FieldData":"Data2" 
          } 
         ] 
        } 
       ] 
      } 
     ] 
    } 
' 

下面是一个嵌套OPENJSON电话,其工作方式的代码的例子,但很复杂,不能动态地生成,我该如何让一个级别的呼叫?

SELECT SectionName, SectionOrder, RenderName, RenderOrder, FieldName, FieldData FROM (
    SELECT SectionName, SectionOrder, RenderName, RenderOrder, Fields FROM (
     select SectionName, SectionOrder, Renders 
     from OPENJSON(@layout,'$.Sections') 
     WITH (
      SectionName nvarchar(MAX) '$.SectionName', 
      SectionOrder nvarchar(MAX) '$.SectionOrder', 
      Renders nvarchar(MAX) '$.Renders' as JSON 
     ) 
    ) as Sections 
    CROSS APPLY OPENJSON(Renders,'$') 
    WITH (
     RenderName nvarchar(MAX) '$.RenderName', 
     RenderOrder nvarchar(MAX) '$.RenderOrder', 
     Fields nvarchar(MAX) '$.Fields' as JSON 
    ) 
) as Renders 
CROSS APPLY OPENJSON(Fields,'$') 
WITH (
    FieldName nvarchar(MAX) '$.FieldName', 
    FieldData nvarchar(MAX) '$.FieldData' 
) 

这是我想达到的目标:

select FieldName, FieldData 
from OPENJSON(@layout,'$.Sections.Renders.Fields') 
WITH (
    FieldName nvarchar(MAX) '$.Sections.Renders.Fields.FieldName', 
    FieldData nvarchar(MAX) '$.Sections.Renders.Fields.FieldData' 
) 
+0

我认为你必须保持'CROSS APPLY'ing - 也就是说,我不知道你可以在一个'OPENJSON'中。 [这个答案能让你得到你需要的东西](https://stackoverflow.com/a/372​​18450/1028230)? – ruffin

回答

0

虽然你不能逃脱只使用单一OPENJSON,可以简化您的查询一下,以便更容易地创建动态删除嵌套的子查询:

SELECT SectionName, SectionOrder, RenderName, RenderOrder, FieldName, FieldData 
FROM OPENJSON(@layout, '$.Sections') 
WITH (
    SectionName NVARCHAR(MAX) '$.SectionName', 
    SectionOrder NVARCHAR(MAX) '$.SectionOrder', 
    Renders NVARCHAR(MAX) '$.Renders' AS JSON 
) 
CROSS APPLY OPENJSON(Renders,'$') 
WITH (
    RenderName NVARCHAR(MAX) '$.RenderName', 
    RenderOrder NVARCHAR(MAX) '$.RenderOrder', 
    Fields NVARCHAR(MAX) '$.Fields' AS JSON 
) 
CROSS APPLY OPENJSON(Fields,'$') 
WITH (
    FieldName NVARCHAR(MAX) '$.FieldName', 
    FieldData NVARCHAR(MAX) '$.FieldData' 
)