简体   繁体   English

如何在 SQL 中解析 Json

[英]How to parse Json in SQL

I try to parse JSON with the function OPENJSON with a CROSS APLY but I have some problems.我尝试使用带有CROSS APLY的函数OPENJSON解析JSON ,但我遇到了一些问题。

My Json is like this:我的 Json是这样的:

 [
   {
      "Communications":[
         {
            "ID_Communication":null,
            "CommunicationType":"HOME",
            "CommunicationValue":"0602060206",
            "Priority":0,
            "Disabled":false
         },
         {
            "ID_Communication":null,
            "CommunicationType":"MOBILE",
            "CommunicationValue":"0602060306",
            "Priority":0,
            "Disabled":false
         },
         {
            "ID_Communication":null,
            "CommunicationType":"EMAIL",
            "CommunicationValue":"MONEMAIL@EMAIL.FR",
            "Priority":0,
            "Disabled":false
         }
      ],
      "InternalId":23126,
      "ExternalId":"",
      "LastUpdateDate":"2020-01-05T12:04:53",
      "Type1":{
         "Id":1
      },
      "Type2":{
         "Id":2
      },
      "Type3":null,
      "Title":{
         "Id":1
      },
      "LastName":"TOTO",
      "FirstName":"TITI",
      "OrganizationName":"",
      "Sex":"M",
      "BirthDate":"1959-10-07T00:00:00",
      "Adresses":[
         {
            "ID_Address":null,
            "Address1":"1 RUE DE FRANCE",
            "Address2":"",
            "Address3":"",
            "Address4":null,
            "ZipCode":"94500",
            "CityName":"MA VILLE",
            "Country":{
               "Id":"FR"
            },
            "Type":null,
            "State":null,
            "Priority":0,
            "ScopeId":0
         }
      ],
      "Language":{
         "Id":"FR"
      },
      "Comment":"",
      "PassportNumber":"",
      "IdentityCardNumber":"",
      "Nationality":null,
      "SocialGroup":{
         "Id":1
      },
      "OptIns":[
         {
            "OptInType":"OPT_CLUB",
            "OptInLabel":"Optin club",
            "OptInValue":0
         },
         {
            "OptInType":"OPT_PART",
            "OptInLabel":"Optin partenaires",
            "OptInValue":0
         }
      ],
      "WebLogin":"MONEMAIL@EMAIL.FR"
   }
]

I have try a query like this: This Query try to get differents informations about this JSON.我尝试过这样的查询:此查询尝试获取有关此 JSON 的不同信息。

declare @JSON_CONTACT nvarchar(MAX)

SELECT @JSON_CONTACT = '[
   {
      "Communications":[
         {
            "ID_Communication":null,
            "CommunicationType":"HOME",
            "CommunicationValue":"0602060206",
            "Priority":0,
            "Disabled":false
         },
         {
            "ID_Communication":null,
            "CommunicationType":"MOBILE",
            "CommunicationValue":"0602060306",
            "Priority":0,
            "Disabled":false
         },
         {
            "ID_Communication":null,
            "CommunicationType":"EMAIL",
            "CommunicationValue":"MONEMAIL@EMAIL.FR",
            "Priority":0,
            "Disabled":false
         }
      ],
      "InternalId":23126,
      "ExternalId":"",
      "LastUpdateDate":"2020-01-05T12:04:53",
      "Type1":{
         "Id":1
      },
      "Type2":{
         "Id":2
      },
      "Type3":null,
      "Title":{
         "Id":1
      },
      "LastName":"TOTO",
      "FirstName":"TITI",
      "OrganizationName":"",
      "Sex":"M",
      "BirthDate":"1959-10-07T00:00:00",
      "Adresses":[
         {
            "ID_Address":null,
            "Address1":"1 RUE DE FRANCE",
            "Address2":"",
            "Address3":"",
            "Address4":null,
            "ZipCode":"94500",
            "CityName":"MA VILLE",
            "Country":{
               "Id":"FR"
            },
            "Type":null,
            "State":null,
            "Priority":0,
            "ScopeId":0
         }
      ],
      "Language":{
         "Id":"FR"
      },
      "Comment":"",
      "PassportNumber":"",
      "IdentityCardNumber":"",
      "Nationality":null,
      "SocialGroup":{
         "Id":1
      },
      "OptIns":[
         {
            "OptInType":"OPT_CLUB",
            "OptInLabel":"Optin club",
            "OptInValue":0
         },
         {
            "OptInType":"OPT_PART",
            "OptInLabel":"Optin partenaires",
            "OptInValue":0
         }
      ],
      "WebLogin":"MONEMAIL@EMAIL.FR"
   }
]'

DROP TABLE TEMP_JSON_RCT_TEST_PARSE

SELECT *
INTO TEMP_JSON_RCT_TEST_PARSE   
FROM OPENJSON (@JSON_CONTACT)
WITH (  
        FIRSTNAME nvarchar(50) '$.FirstName',
        LASTNAME nvarchar(50) '$.LastName',
        Sex nvarchar(2) '$.Sex',
        BirthDate date  '$.BirthDate',
        Communications nvarchar(max) AS JSON
) AS Communications
CROSS APPLY OPENJSON(Communications)
WITH (
    CommunicationType  nvarchar(50),
    CommunicationValue nvarchar(50),
    Adresses nvarchar(max) AS JSON
) AS Adresses
CROSS APPLY OPENJSON(Adresses)
WITH (
    Address1 nvarchar(100)
)

I would like my select return:我希望我的选择返回:

FIRSTNAME, LASTNAME, SEX, BIRTHDATE, EMAIL, MOBILE, HOME, LASTUPDATEDATE, ADDRESS1, ADRESSE2, ADDRESSE3, ADDRESS4, ZIPCODE, CITYNAME, OPT_CLUB, OPT_PART

VALUES:
MY FIRSTNAME, MYLASTNAME, M, 09/05/1989, MONEMAIL@EMAIL.FR, 0602060306,0602060206, 2020-01-05T12:04:53, 1 RUE DE FRANCE, , , , 94500, MA VILLE, 0, 0

When I execute my query, that return null, I don't understand why.当我执行查询时,返回 null,我不明白为什么。

Can you help about this ?你能帮忙解决这个问题吗?

Address is part of main entity地址是主要实体的一部分

SELECT *
FROM OPENJSON (@JSON_CONTACT)
WITH (  
        FIRSTNAME nvarchar(50) '$.FirstName',
        LASTNAME nvarchar(50) '$.LastName',
        Sex nvarchar(2) '$.Sex',
        BirthDate date  '$.BirthDate',
        Communications nvarchar(max) AS JSON,
        Adresses nvarchar(max) AS JSON
) AS Communications
CROSS APPLY OPENJSON(Communications)
WITH (
    CommunicationType  nvarchar(50),
    CommunicationValue nvarchar(50)    
) AS Adresses
CROSS APPLY OPENJSON(Adresses)
WITH (
    Address1 nvarchar(100)
)

This seems to return your expected results, but note that this works only if OptIns and Communications JSON arrays has the structure in the question.这似乎返回了您的预期结果,但请注意,这仅在OptInsCommunications JSON 数组具有问题中的结构时才OptIns You need to use OPENJSON() with explicit schema and AS JSON clause for nested JSON arrays:您需要将OPENJSON()与显式架构和AS JSON子句一起用于嵌套的 JSON 数组:

SELECT 
   FIRSTNAME, LASTNAME, SEX, BIRTHDATE, 
   EMAIL, MOBILE, HOME, 
   LASTUPDATEDATE, ADDRESS1, ADDRESS2, ADDRESS3, ADDRESS4, ZIPCODE, CITYNAME,
   OPT_CLUB, OPT_PART
FROM OPENJSON(@JSON_CONTACT, '$') WITH (
   FIRSTNAME nvarchar(100) '$.FirstName',
   LASTNAME nvarchar(100) '$.LastName',
   SEX nvarchar(1) '$.Sex',
   BIRTHDATE nvarchar(100) '$.BirthDate',
   Communications nvarchar(max) '$.Communications' AS JSON,
   Adresses nvarchar(max) '$.Adresses' AS JSON,
   LASTUPDATEDATE nvarchar(100) '$.LastUpdateDate',
   OptIns nvarchar(max) '$.OptIns' AS JSON
) j1
CROSS APPLY (
   SELECT
      MAX(CASE WHEN CommunicationType = 'EMAIL' THEN CommunicationValue END) AS EMAIL,
      MAX(CASE WHEN CommunicationType = 'MOBILE' THEN CommunicationValue END) AS MOBILE,
      MAX(CASE WHEN CommunicationType = 'HOME' THEN CommunicationValue END) AS HOME
   FROM OPENJSON(j1.Communications) WITH (
      CommunicationType nvarchar(100) '$.CommunicationType',
      CommunicationValue nvarchar(100) '$.CommunicationValue'
   )   
) j2
CROSS APPLY OPENJSON(j1.Adresses) WITH (
   ADDRESS1 nvarchar(100) '$.Address1',
   ADDRESS2 nvarchar(100) '$.Address2',
   ADDRESS3 nvarchar(100) '$.Address3',
   ADDRESS4 nvarchar(100) '$.Address4',
   ZIPCODE nvarchar(100) '$.ZipCode',
   CITYNAME nvarchar(100) '$.CityName'
) j3
CROSS APPLY (
   SELECT
      MAX(CASE WHEN OptInType = 'OPT_CLUB' THEN OptInValue END) AS OPT_CLUB,
      MAX(CASE WHEN OptInType = 'OPT_PART' THEN OptInValue END) AS OPT_PART
   FROM OPENJSON(j1.OptIns) WITH (
      OptInType nvarchar(100) '$.OptInType',
      OptInValue int '$.OptInValue'
   )   
) j4

Result (with the JOSN in the question):结果(问题中有 JOSN):

FIRSTNAME   LASTNAME    SEX BIRTHDATE           EMAIL               MOBILE      HOME        LASTUPDATEDATE      ADDRESS1        ADDRESS2    ADDRESS3    ADDRESS4    ZIPCODE CITYNAME    OPT_CLUB    OPT_PART
TITI        TOTO        M   1959-10-07T00:00:00 MONEMAIL@EMAIL.FR   0602060306  0602060206  2020-01-05T12:04:53 1 RUE DE FRANCE                                     94500   MA VILLE    0           0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM