2016-05-13 287 views
12

我有一些json,我想在SQL Server 2016中解析。有一個Projects-> Structures-> Properties的層次結構。我想編寫解析整個層次的查詢,但我不希望指定索引號的任何元素,即我不想做這樣的事:SQL Server OPENJSON讀取嵌套的json

openjson (@json, '$[0]') 

openjson (@json, '$.structures[0]') 

我有這個想法,我可以讀取頂級項目對象的值以及表示它下面的結構的json字符串,然後可以單獨解析這些結構。問題是,下面的代碼無法正常工作:

declare @json nvarchar(max) 
set @json = ' 
[ 
    { 
     "IdProject":"97A76363-095D-4FAB-940E-9ED2722DBC47", 
     "Name":"Test Project", 
     "structures":[ 
     { 
      "IdStructure":"CB0466F9-662F-412B-956A-7D164B5D358F", 
      "IdProject":"97A76363-095D-4FAB-940E-9ED2722DBC47", 
      "Name":"Test Structure", 
      "BaseStructure":"Base Structure", 
      "DatabaseSchema":"dbo", 
      "properties":[ 
       { 
        "IdProperty":"618DC40B-4D04-4BF8-B1E6-12E13DDE86F4", 
        "IdStructure":"CB0466F9-662F-412B-956A-7D164B5D358F", 
        "Name":"Test Property 2", 
        "DataType":1, 
        "Precision":0, 
        "Scale":0, 
        "IsNullable":false, 
        "ObjectName":"Test Object", 
        "DefaultType":1, 
        "DefaultValue":"" 
       }, 
       { 
        "IdProperty":"FFF433EC-0BB5-41CD-8A71-B5F09B97C5FC", 
        "IdStructure":"CB0466F9-662F-412B-956A-7D164B5D358F", 
        "Name":"Test Property 1", 
        "DataType":1, 
        "Precision":0, 
        "Scale":0, 
        "IsNullable":false, 
        "ObjectName":"Test Object", 
        "DefaultType":1, 
        "DefaultValue":"" 
       } 
      ] 
     } 
     ] 
    } 
]'; 

select IdProject, Name, structures 
from openjson (@json) 
with 
(
    IdProject uniqueidentifier, 
    Name nvarchar(100), 
    structures nvarchar(max) 
) as Projects 

IdProject和名稱得到恢復沒有問題,但由於某種原因,我不能在「結構」舉行的嵌套JSON。取而代之的是JSON內容只是它返回NULL:

enter image description here

有誰知道這是可能的,如果是的話,我究竟做錯了什麼?

回答

20

如果引用JSON對象或數組,你需要指定爲JSON子句:

select IdProject, Name, structures 
from openjson (@json) 
with 
(
    IdProject uniqueidentifier, 
    Name nvarchar(100), 
    structures nvarchar(max) AS JSON 
) as Projects 

參見常見問題解答: https://msdn.microsoft.com/en-us/library/mt631706.aspx#Anchor_6

如果你想返回的結構數組上應用OPENJSON,你可以使用類似下面的代碼:

select IdProject, Name, structures 
from openjson (@json) 
with 
(
    IdProject uniqueidentifier, 
    Name nvarchar(100), 
    structures nvarchar(max) AS JSON 
) as Projects 
    CROSS APPLY OPENJSON (structures) WITH (......) 
1

典型!我在發佈問題後才找到答案。你需要指定的列時,使用「作爲JSON」關鍵字返回:

select IdProject, Name, structures 
from openjson (@json) 
with 
(
    IdProject uniqueidentifier, 
    Name nvarchar(100), 
    structures nvarchar(max) as json 
) as Projects 
6

使用CROSS APPLY:

declare @json nvarchar(max) 
set @json = ' 
[ 
    { 
     "IdProject":"97A76363-095D-4FAB-940E-9ED2722DBC47", 
     "Name":"Test Project", 
     "structures":[ 
     { 
      "IdStructure":"CB0466F9-662F-412B-956A-7D164B5D358F", 
      "IdProject":"97A76363-095D-4FAB-940E-9ED2722DBC47", 
      "Name":"Test Structure", 
      "BaseStructure":"Base Structure", 
      "DatabaseSchema":"dbo", 
      "properties":[ 
       { 
        "IdProperty":"618DC40B-4D04-4BF8-B1E6-12E13DDE86F4", 
        "IdStructure":"CB0466F9-662F-412B-956A-7D164B5D358F", 
        "Name":"Test Property 2", 
        "DataType":1, 
        "Precision":0, 
        "Scale":0, 
        "IsNullable":false, 
        "ObjectName":"Test Object", 
        "DefaultType":1, 
        "DefaultValue":"" 
       }, 
       { 
        "IdProperty":"FFF433EC-0BB5-41CD-8A71-B5F09B97C5FC", 
        "IdStructure":"CB0466F9-662F-412B-956A-7D164B5D358F", 
        "Name":"Test Property 1", 
        "DataType":1, 
        "Precision":0, 
        "Scale":0, 
        "IsNullable":false, 
        "ObjectName":"Test Object", 
        "DefaultType":1, 
        "DefaultValue":"" 
       } 
      ] 
     } 
     ] 
    } 
]'; 

select 
    Projects.IdProject, Projects.Name as NameProject, 
    Structures.IdStructure, Structures.Name as NameStructure, Structures.BaseStructure, Structures.DatabaseSchema, 
    Properties.*  
from openjson (@json) 
with 
(
    IdProject uniqueidentifier, 
    Name nvarchar(100), 
    structures nvarchar(max) as json 
) 
as Projects 
cross apply openjson (Projects.structures) 
with 
(
    IdStructure uniqueidentifier, 
    Name nvarchar(100), 
    BaseStructure nvarchar(100), 
    DatabaseSchema sysname, 
    properties nvarchar(max) as json 
) as Structures 
cross apply openjson (Structures.properties) 
with 
(
    IdProperty uniqueidentifier, 
    NamePreoperty nvarchar(100) '$.Name', 
    DataType int, 
    [Precision] int, 
    [Scale] int, 
    IsNullable bit, 
    ObjectName nvarchar(100), 
    DefaultType int, 
    DefaultValue nvarchar(100) 
) 
as Properties