【问题标题】:How to work out the path for all values in a JSON如何计算出 JSON 中所有值的路径
【发布时间】:2020-12-04 13:56:06
【问题描述】:

我有一个 JSON 列,其中包含价值约 300k 的属性,我想尝试以能够获取属性的完整路径和值的方式导出它。 请注意,我的 JSON 没有数组 - 它基本上是用于 Web 应用程序翻译的 JSON。

为了提供一个带有以下 JSON 的简单示例,我想返回以下内容:

JSON: {"Name":"Jeff", "Address": {"Street": "123 Harrow Street", "City": "Dublin"}}

预期输出:

|----------------|-------------------|
| path           |  value            |
|----------------|-------------------|
| Name           | Jeff              |
| Address.Street | 123 Harrow Street |
| Address.City   | Dublin            |
|----------------|-------------------|

或者,如果更简单,我可以使用 $.,因为我希望能够轻松更新每个属性的值 - 使用 JSON_MODIFY

我尝试过使用 OPENJSON,但它似乎只返回 3 个字段键、值和类型,但至少这里的键没有超出值的字段级别,所以我得到: 查询:

DECLARE @json_doc nvarchar(4000) = '{"Name":"Jeff", "Address": {"Street": "123 Harrow Street", "City": "Dublin"}}';

SELECT [key], [value]
FROM OPENJSON(@json_doc);
GO

输出:

|---------|---------------------------------------------------|
| key     |  value                                            |
|---------|---------------------------------------------------|
| Name    | Jeff                                              |
| Address | {"Street": "123 Harrow Street", "City": "Dublin"} |
|---------|---------------------------------------------------|

有没有办法让 OPENJSON 查询完全递归?还是有其他方法?我试过谷歌搜索,但这似乎不是一个常见的请求?

【问题讨论】:

    标签: sql-server open-json


    【解决方案1】:

    递归 CTE 是一种选择。您需要在查询的递归成员中使用ISJSON() 作为终止条件:

    DECLARE @json_doc nvarchar(4000) = '{"Name":"Jeff", "Address": {"Street": "123 Harrow Street", "City": "Dublin"}}';
    
    ;WITH rCTE AS (
       SELECT 
           CONVERT(nvarchar(max), N'$') COLLATE DATABASE_DEFAULT AS [path], 
           CONVERT(nvarchar(max), JSON_QUERY(@json_doc, '$')) COLLATE DATABASE_DEFAULT AS [value]
       UNION ALL
       SELECT 
          CONVERT(nvarchar(max), CONCAT(r.path, CONCAT(N'.', c.[key]))) COLLATE DATABASE_DEFAULT ,
          CONVERT(nvarchar(max), c.[value]) COLLATE DATABASE_DEFAULT                                        
       FROM rCTE r
       CROSS APPLY OPENJSON(r.[value]) c
       WHERE ISJSON(r.[value]) = 1
    )
    SELECT *
    FROM rCTE
    WHERE ISJSON([value]) = 0
    

    结果:

    path             value
    ----------------------------------
    $.Name           Jeff
    $.Address.Street 123 Harrow Street
    $.Address.City   Dublin
    

    【讨论】:

    • 完美,非常感谢,这很有魅力。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多