【问题标题】:Parse Nested JSON to Azure SQL table将嵌套的 JSON 解析为 Azure SQL 表
【发布时间】:2021-05-26 07:17:58
【问题描述】:

我编写了一个函数,它从 API 请求一些数据并将其转储到存储帐户中。然后我使用this 方法访问 Azure SQL DB 中的数据。一切都按预期工作,但我留下了以下查找表:

+-----+-----------------------------------------------------------------------------------------------------------------------------+--------+
| key |                                                             value                                                           |   type |
+-----+-----------------------------------------------------------------------------------------------------------------------------+--------+
|   0 |    {"Localnumber": "1200", "Name": "Hovednummer - IT", "Description": null, "Email": "", "PhoneNumbers": [], "Phones": ...} |      5 |
+-----+-----------------------------------------------------------------------------------------------------------------------------+--------+

JSON 值如下所示:

[
  {
    "Localnumber": "626",
    "Name": "name",
    "Description": null,
    "Email": "email",
    "PhoneNumbers": [
      {
        "Number": "88888888",
        "LineName": null,
        "BelongsTo": "626",
        "GotoLocalNumber": null
      },
      {
        "Number": "12345678",
        "LineName": null,
        "BelongsTo": "626",
        "GotoLocalNumber": null
      }
    ],
    "Phones": [
      {
        "LocalNumber": "200018",
        "Name": null,
        "Type": 21,
        "MAC": null,
        "BelongsTo": "626",
        "description": "Myfone"
      },
      {
        "LocalNumber": "200273",
        "Name": null,
        "Type": 8,
        "MAC": "40859694",
        "BelongsTo": "626",
        "description": "mobile"
      },
      {
        "LocalNumber": "200449",
        "Name": null,
        "Type": 23,
        "MAC": null,
        "BelongsTo": "626",
        "description": "test"
      }
    ],
    "Info": [
      {
        "Type": 0,
        "Label": null,
        "Value": null
      }
    ],
    "Department": {
      "Name": "name",
      "Street": "Street",
      "Zipcode": "1111",
      "City": "City",
      "Cvr": "123456798",
      "Contact": "Contact",
      "Email": "email",
      "Ean": null,
      "Iref": null
    }
  }
]

如何将其插入到新表中,以便每个 JSON 值看起来像这样:

+-------------+---------+-------------+-------+---------------------+-----------------------+------------------------+------------------------------+--------------------+-------------+-------------+------------+------------------+--------------------+-----------+------------+------------+-----------------+-------------------+--------------------+-----------------+----------------+--------------------+-------------------+----------------+-----------------+
| Localnumber |  Name   | Description | Email | PhoneNumbers_Number | PhoneNumbers_LineName | PhoneNumbers_BelongsTo | PhoneNumbers_GotoLocalNumber | Phones_LocalNumber | Phones_Name | Phones_Type | Phones_MAC | Phones_BelongsTo | Phones_description | Info_Type | Info_Label | Info_Value | Department_Name | Department_Street | Department_Zipcode | Department_City | Department_Cvr | Department_Contact | Department_Email  | Department_Ean | Department_Iref |
+-------------+---------+-------------+-------+---------------------+-----------------------+------------------------+------------------------------+--------------------+-------------+-------------+------------+------------------+--------------------+-----------+------------+------------+-----------------+-------------------+--------------------+-----------------+----------------+--------------------+-------------------+----------------+-----------------+
|        1213 | Z3C (1) | NULL        | NULL  | 20813221            | NULL                  | 1213                   | NULL                         | NULL               | NULL        | NULL        | NULL       | NULL             | NULL               | NULL      | NULL       | NULL       | NULL            | NULL              | NULL               | NULL            | NULL           | NULL               | NULL              | NULL           | NULL            |
|        1213 | Z3C (1) | NULL        | NULL  | NULL                | NULL                  | NULL                   | NULL                         | 200013             | NULL        | 21          | NULL       | 1213             | Myfone             | NULL      | NULL       | NULL       | NULL            | NULL              | NULL               | NULL            | NULL           | NULL               | NULL              | NULL           | NULL            |
|        1213 | Z3C (1) | NULL        | NULL  | NULL                | NULL                  | NULL                   | NULL                         | 200270             | NULL        | 8           | 20813221   | 1213             | Mobil (20813221)   | NULL      | NULL       | NULL       | NULL            | NULL              | NULL               | NULL            | NULL           | NULL               | NULL              | NULL           | NULL            |
|        1213 | Z3C (1) | NULL        | NULL  | NULL                | NULL                  | NULL                   | NULL                         | NULL               | NULL        | NULL        | NULL       | NULL             | NULL               | 0         | NULL       | NULL       | NULL            | NULL              | NULL               | NULL            | NULL           | NULL               | NULL              | NULL           | NULL            |
|        1213 | Z3C (1) | NULL        | NULL  | NULL                | NULL                  | NULL                   | NULL                         | NULL               | NULL        | NULL        | NULL       | NULL             | NULL               | NULL      | NULL       | NULL       | Obton A/S       | Silkeborgvej 2    | 8000               | Aarhus          | 31596106       | Søren Thygesen     | faktura@obton.com | NULL           | NULL            |
+-------------+---------+-------------+-------+---------------------+-----------------------+------------------------+------------------------------+--------------------+-------------+-------------+------------+------------------+--------------------+-----------+------------+------------+-----------------+-------------------+--------------------+-----------------+----------------+--------------------+-------------------+----------------+-----------------+

编辑

因此,以下查询帮助我实现了我正在搜索的内容。

SELECT GO.LocalNumber
    ,GO.Name
    ,GO.Description
    ,GO.Email
    ,json.Number
    ,json.LineName
    ,json.Belongsto
    ,json.GoToLocalNumber
    ,go2.LocalNumber
    ,go2.Name
    ,go2.Type
    ,go2.MAC
    ,go2.BelongsTo
    ,go2.description 'description_phones'
    ,go3.Type 'Info_Type'
    ,go3.Label
    ,go3.Value
    ,go4.Name
    ,go4.Street
    ,go4.Zipcode
    ,go4.City
    ,go4.Cvr
    ,go4.Contact
    ,go4.Email
    ,go4.Ean
    ,go4.Iref
FROM openrowset(BULK 'flexfoneoutputblob/data', DATA_SOURCE = 'FlexfoneBlobStorage', SINGLE_CLOB) AS AzureBlob
CROSS APPLY OPENJSON(BulkColumn) WITH (
        Localnumber INT
        ,Name NVARCHAR(250)
        ,Description NVARCHAR(250)
        ,Email NVARCHAR(250)
        ,PhoneNumbers NVARCHAR(MAX) AS json
        ,Phones NVARCHAR(MAX) AS json
        ,Info NVARCHAR(MAX) AS json
        ,Department NVARCHAR(MAX) AS json
        ) AS GO
CROSS APPLY OPENJSON(PhoneNumbers) WITH (
        Number NVARCHAR(20)
        ,LineName NVARCHAR(20)
        ,BelongsTo NVARCHAR(10)
        ,GotoLocalNumber NVARCHAR(20)
        ) AS json
CROSS APPLY OPENJSON(Phones) WITH (
        LocalNumber NVARCHAR(20)
        ,Name NVARCHAR(50)
        ,Type INT
        ,MAC NVARCHAR(20)
        ,BelongsTo NVARCHAR(20)
        ,description NVARCHAR(30)
        ) AS go2
CROSS APPLY OPENJSON(Info) WITH (
        Type INT
        ,Label NVARCHAR(20)
        ,Value NVARCHAR(20)
        ) AS go3
CROSS APPLY OPENJSON(Department) WITH (
        Name NVARCHAR(20)
        ,Street NVARCHAR(20)
        ,Zipcode NVARCHAR(20)
        ,City NVARCHAR(20)
        ,Cvr NVARCHAR(20)
        ,Contact NVARCHAR(20)
        ,Email NVARCHAR(20)
        ,Ean NVARCHAR(20)
        ,Iref NVARCHAR(20)
        ) AS go4

【问题讨论】:

  • 对value的每一列数据,获取json字符串,将json字符串设置为参数,然后将这些数据插入到表中。示例:sqlshack.com/how-to-parse-json-in-sql-server
  • 根据问题指南,请不要发布代码、数据、错误消息等的图像 - 将文本复制或输入到问题中。请保留将图像用于图表或演示渲染错误,无法通过文本准确描述的事情。
  • 您不想将PhonesDepartment 放在单独的表格中吗?
  • @Charlieface 是的,我愿意。我可能会尝试从中创建几个表。只是不确定如何为此创建正确的键,所以我将使用一张大表。
  • @Charlieface 意识到我可以只使用两个表中的 uniqeu 列之一。

标签: sql-server azure azure-sql-database


【解决方案1】:

如果你想把它放到单独的表中,你可以使用SCOPE_IDENTITY 来获取前一个插入的 ID。

由于根对象在数组中,需要将路径改为$[0]

DECLARE @json nvarchar(max) = (
    SELECT BulkColumn
    FROM openrowset(BULK 'flexfoneoutputblob/data', DATA_SOURCE = 'FlexfoneBlobStorage', SINGLE_CLOB)
);

SELECT LocalNumber
    ,Name
    ,Description
    ,Email
FROM OPENJSON(@json, '$[0]') WITH (
        Localnumber INT
        ,Name NVARCHAR(250)
        ,Description NVARCHAR(250)
        ,Email NVARCHAR(250)
        ) AS G;

DECLARE @id int = SCOPE_IDENTITY();

INSERT PhoneNumber
    (GId, Number, LineName, BelongsTo, GotoLocalNumber)
SELECT @id, Number, LineName, BelongsTo, GotoLocalNumber
FROM OPENJSON(@json, '$[0].PhoneNumbers') WITH (
        Number NVARCHAR(20)
        ,LineName NVARCHAR(20)
        ,BelongsTo NVARCHAR(10)
        ,GotoLocalNumber NVARCHAR(20)
        ) AS json;

INSERT Phone
    (GId, LocalNumber, Name, Type, MAC, BelongsTo, description)
SELECT @id, LocalNumber, Name, Type, MAC, BelongsTo, description
FROM OPENJSON(@json, '$[0].Phones') WITH (
        LocalNumber NVARCHAR(20)
        ,Name NVARCHAR(50)
        ,Type INT
        ,MAC NVARCHAR(20)
        ,BelongsTo NVARCHAR(20)
        ,description NVARCHAR(30)
        ) AS go2;

INSERT Info
    (GId, Type, Label, Value)
SELECT @id, Type, Label, Value
FROM OPENJSON(@json, '$[0].Info') WITH (
        Type INT
        ,Label NVARCHAR(20)
        ,Value NVARCHAR(20)
        ) AS go3

INSERT Department
    (GId, Name, Street, Zipcode, City, Cvr, Contact, Email, Ean, Iref)
SELECT @id, Name, Street, Zipcode, City, Cvr, Contact, Email, Ean, Iref
FROM OPENJSON(@json, '$[0].Department') WITH (
        Name NVARCHAR(20)
        ,Street NVARCHAR(20)
        ,Zipcode NVARCHAR(20)
        ,City NVARCHAR(20)
        ,Cvr NVARCHAR(20)
        ,Contact NVARCHAR(20)
        ,Email NVARCHAR(20)
        ,Ean NVARCHAR(20)
        ,Iref NVARCHAR(20)
        ) AS go4

对于根对象和Department,您也可以使用JSON_VALUE,因为只有一个对象

【讨论】:

  • 这很好,但我认为FROM AS AzureBlob 周围有一个错字。
  • 为什么只有INSERT而不是INSERT INTO
  • 抱歉已修复。 INTO 是可选的。 INSERT 中的列名也是可选的,但最好始终包含它们
  • 出于某种原因,INSERT 没有插入任何内容。桌子还是空的。
  • 你从SELECT 得到什么,应该是一样的?您的 实际 JSON 与上述有多相似,您可能需要调整路径(第二个参数为OPENJSON
猜你喜欢
  • 2022-08-20
  • 2011-12-24
  • 1970-01-01
  • 2021-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多