OPENJSON - 解析嵌套的 JSON 保留关系

问题描述 投票:0回答:1

我有一个像这样的 JSON 数组

[
  {
    "_id": "12345",
    "uniqueId": null,
    "companyName": "ABC Corp",
    "yearFounded": 1958,
    "stateFounded": "Delaware",
    "someField": [
      {
        "primaryCode": "14",
        "secondaryCode": "32",
        "tertiaryCode": "00",
        "description": "Moving Walks"
      },
      {
        "primaryCode": "14",
        "secondaryCode": "40",
        "tertiaryCode": "00",
        "description": "Lifts"
      },
      {
        "primaryCode": "14",
        "secondaryCode": "00",
        "tertiaryCode": "00",
        "description": "Conveying Equipment"
      }
    ],
    "SomeRegionProperty": [
      {
        "region": "Other"
      },
      {
        "region": "MD - Eastern Shore"
      },
      {
        "region": "MD - Southern"
      },
      {
        "region": "MD - Central (incl. Baltimore)"
      }
    ],
    "Markets": [
      {
        "market": "Pharmaceutical & Laboratory"
      },
      {
        "market": "Retail"
      }
    ],
    "SomeEmptyProperty": [],
    "AndYetAnother": [
      {
        "unionName": "Name",
        "unionNumber": "Value 1234"
      }
    ]
  },
  {
    "_id": "949690",
    "companyName": "XYZ Co",
    "yearFounded": 2015,
    "stateFounded": "New York",
    "someField": [
      {
        "primaryCode": "15",
        "secondaryCode": "62",
        "tertiaryCode": "032",
        "description": "test"
      }
    ],
    "SomeRegionProperty": [
      {
        "region": "Other"
      },
      {
        "region": "MD - Eastern Shore"
      },
      {
        "region": "MD - Southern"
      },
      {
        "region": "MD - Central (incl. Baltimore)"
      }
    ],
    "Markets": [
      {
        "market": "Pharmaceutical & Laboratory"
      },
      {
        "market": "Retail"
      }
    ],
    "SomeEmptyProperty": [],
    "AndYetAnother": [
      {
        "unionName": "Name",
        "unionNumber": "Value 1234"
      }
    ]
  }
]

所以,我需要将对象分发到sql表中(sql server) 使用表“MainTbl” - 最外层字段作为列,_id 作为主键。 每个嵌套部分的表(“SomField”、“SomeRegionProperty”、“Markets”.. 等等),_id 是这些表中的外键。

我知道 openJson 返回一个表值。但是,如何在为“someField”插入 3 条记录时保留 _id=12345?等...

我想以这样的结构结束

而且我的 JSON 可以很大,可以有很多相关的表,有很多字段。因此,在主输入上多次通过

OPENJSON
并不是太可取。它可能会减慢该过程。 但是,如果没有其他办法,我会接受它。

sql json sql-server open-json
1个回答
0
投票

首先你可以使用 openjson 和 Cte 获取数据 MainTbl

第二,您使用 openjson 和 Cte 获取 DataSomeFieldTbl 并使用 json

;with _list  as(
SELECT  
        a.uniqueId
            ,_id
        ,companyName
        ,yearFounded
   
  
        ,stateFounded
   

    FROM
    OPENJSON(@json)
    WITH
    (
            uniqueId varchar(100) N'$.uniqueId'
            ,_id varchar(100) N'$._id' 
        ,companyName varchar(100) N'$.companyName'
        ,yearFounded varchar(100) N'$.yearFounded'
        ,stateFounded varchar(100) N'$.stateFounded'

        
) AS a 

)

insert into MainTbl
(
         id  
        ,uniqueId 
        ,companyName 
         ,yearFounded 
         ,stateFounded 
 )
select 
         _id  
        ,uniqueId 
        ,companyName 
         ,yearFounded 
         ,stateFounded                                         
from _list  



;with _list  as(
SELECT  
            primaryCode
           ,secondaryCode
           ,_id
           ,tertiaryCode
           ,description

    FROM
    OPENJSON(@json)
    WITH
    (
         _id varchar(100) N'$._id' 
        ,someField NVARCHAR(MAX) AS JSON
) AS a
CROSS APPLY
OPENJSON(a.someField)
WITH
(
    primaryCode varchar(100) N'$.primaryCode'
    ,secondaryCode varchar(100) N'$.secondaryCode'
    ,tertiaryCode varchar(100) N'$.tertiaryCode'
    ,description varchar(100) N'$.description'

) AS b

)

insert into SomeFieldTbl
(
         Id_FK  
        ,primaryCode 
        ,secondaryCode 
         ,tertiaryCode 
         ,description 
 )
select  
         _id  
        ,primaryCode 
        ,secondaryCode 
         ,tertiaryCode 
         ,description                                          
from _list  

下面的代码包含了完整的代码,包括创建一个表和向两个表插入数据


drop table if exists SomeFieldTbl
drop table if exists MainTbl


create table SomeFieldTbl(
Id_FK varchar(100),
primaryCode varchar(100)
,secondaryCode varchar(100),tertiaryCode varchar(100) 
 ,description varchar(100)
 )

create table MainTbl(
id varchar(100)
,uniqueId varchar(100),companyName varchar(100) 
 ,yearFounded varchar(100)
 ,stateFounded varchar(100))


declare @json varchar(max)='[
  {
    "_id": "12345",
    "uniqueId": null,
    "companyName": "ABC Corp",
    "yearFounded": 1958,
    "stateFounded": "Delaware",
    "someField": [
      {
        "primaryCode": "14",
        "secondaryCode": "32",
        "tertiaryCode": "00",
        "description": "Moving Walks"
      },
      {
        "primaryCode": "14",
        "secondaryCode": "40",
        "tertiaryCode": "00",
        "description": "Lifts"
      },
      {
        "primaryCode": "14",
        "secondaryCode": "00",
        "tertiaryCode": "00",
        "description": "Conveying Equipment"
      }
    ],
    "SomeRegionProperty": [
      {
        "region": "Other"
      },
      {
        "region": "MD - Eastern Shore"
      },
      {
        "region": "MD - Southern"
      },
      {
        "region": "MD - Central (incl. Baltimore)"
      }
    ],
    "Markets": [
      {
        "market": "Pharmaceutical & Laboratory"
      },
      {
        "market": "Retail"
      }
    ],
    "SomeEmptyProperty": [],
    "AndYetAnother": [
      {
        "unionName": "Name",
        "unionNumber": "Value 1234"
      }
    ]
  },
  {
    "_id": "949690",
    "companyName": "XYZ Co",
    "yearFounded": 2015,
    "stateFounded": "New York",
    "someField": [
      {
        "primaryCode": "15",
        "secondaryCode": "62",
        "tertiaryCode": "032",
        "description": "test"
      }
    ],
    "SomeRegionProperty": [
      {
        "region": "Other"
      },
      {
        "region": "MD - Eastern Shore"
      },
      {
        "region": "MD - Southern"
      },
      {
        "region": "MD - Central (incl. Baltimore)"
      }
    ],
    "Markets": [
      {
        "market": "Pharmaceutical & Laboratory"
      },
      {
        "market": "Retail"
      }
    ],
    "SomeEmptyProperty": [],
    "AndYetAnother": [
      {
        "unionName": "Name",
        "unionNumber": "Value 1234"
      }
    ]
  }
]

'

;with _list  as(
SELECT  
        a.uniqueId
            ,_id
        ,companyName
        ,yearFounded
   
  
        ,stateFounded
   

    FROM
    OPENJSON(@json)
    WITH
    (
            uniqueId varchar(100) N'$.uniqueId'
            ,_id varchar(100) N'$._id' 
        ,companyName varchar(100) N'$.companyName'
        ,yearFounded varchar(100) N'$.yearFounded'
        ,stateFounded varchar(100) N'$.stateFounded'

        
) AS a 

)

insert into MainTbl
(
         id  
        ,uniqueId 
        ,companyName 
         ,yearFounded 
         ,stateFounded 
 )
select 
         _id  
        ,uniqueId 
        ,companyName 
         ,yearFounded 
         ,stateFounded                                         
from _list  



;with _list  as(
SELECT  
            primaryCode
           ,secondaryCode
           ,_id
           ,tertiaryCode
           ,description

    FROM
    OPENJSON(@json)
    WITH
    (
         _id varchar(100) N'$._id' 
        ,someField NVARCHAR(MAX) AS JSON
) AS a
CROSS APPLY
OPENJSON(a.someField)
WITH
(
    primaryCode varchar(100) N'$.primaryCode'
    ,secondaryCode varchar(100) N'$.secondaryCode'
    ,tertiaryCode varchar(100) N'$.tertiaryCode'
    ,description varchar(100) N'$.description'

) AS b

)

insert into SomeFieldTbl
(
         Id_FK  
        ,primaryCode 
        ,secondaryCode 
         ,tertiaryCode 
         ,description 
 )
select  
         _id  
        ,primaryCode 
        ,secondaryCode 
         ,tertiaryCode 
         ,description                                          
from _list  

© www.soinside.com 2019 - 2024. All rights reserved.