使用 sql 存储过程获取 json 字符串中的子节点?

Get Children nodes in json string using sql stored procedure?

我有一个 JSON 字符串传递给存储过程,如下所示,

{"config": {
    "site": "Internal",
    "library": "test-library",
    "folderHierarchy": {
        "name": "folder1",
        "children": {
            "name": "folder2",
            "children": {
                "name": "folder3"
            }
        }
    },
    "meta_data": [{
            "meta_text": "date-created",
            "meta_value": "2020-04-17"
        }, {
            "meta_text": "date-modified",
            "meta_value": "2020-04-17"
        }]
}}

我需要在 folderHierarchy 节点中获取文件夹名称,它可以有很多数字或子文件夹。

首先,我尝试将 folderHierarchy 作为 JSON 字符串并遍历该 JSON 字符串。

DECLARE @CONFIG VARCHAR(MAX) = '{"config": {
    "site": "Internal",
    "library": "test-library",
    "folderHierarchy": {
        "name": "folder1",
        "children": {
            "name": "folder2",
            "children": {
                "name": "folder3"
            }
        }
    },
    "meta_data": [{
            "meta_text": "date-created",
            "meta_value": "2020-04-17"
        }, {
            "meta_text": "date-modified",
            "meta_value": "2020-04-17"
        }]
}}'

DECLARE @folderHierarchy VARCHAR(MAX);
SET @folderHierarchy = JSON_QUERY(@CONFIG, '$.config.folderHierarchy');
SELECT  @folderHierarchy;

SELECT  *
FROM    openjson(@folderHierarchy)
        WITH(
            name VARCHAR(max) '$.name',
            childern NVARCHAR(MAX) '$.children' AS JSON
        ) AS P
        OUTER APPLY OPENJSON(P.childern)
        WITH (name NVARCHAR(MAX) '$.name');

但这给了我第一个和第二个文件夹名称。

任何人都可以帮我得到所有的文件夹名称,主要是我无法控制文件夹中子项目的数量。

我的意思是文件夹 1 可以有名为文件夹 2 的文件夹,文件夹 2 可以有名为文件夹 3 的文件夹,文件夹 3 可以有名为文件夹 4 的文件夹,依此类推。

您可以为此使用递归 CTE。 SQL 服务器上的默认设置将允许您递归 up to 100 levels deep(参见 MAXRECUSRION)...

declare @Config nvarchar(max) =
N'{"config": {
    "site": "Internal",
    "library": "test-library",
    "folderHierarchy": {
        "name": "folder1",
        "children": {
            "name": "folder2",
            "children": {
                "name": "folder3"
            }
        }
    },
    "meta_data": [{
            "meta_text": "date-created",
            "meta_value": "2020-04-17"
        }, {
            "meta_text": "date-modified",
            "meta_value": "2020-04-17"
        }]
}}';

with JsonFolders as (
    select
        1 as level,
        name,
        children
    from openjson(@Config, N'$.config.folderHierarchy') with (
      name nvarchar(max) N'$.name',
      children nvarchar(max) N'$.children' as json
    )
    union all
    select
        1 + level,
        Child.name,
        Child.children
    from JsonFolders JF
    cross apply openjson(JF.children) with (
      name nvarchar(max) N'$.name',
      children nvarchar(max) N'$.children' as json
    ) Child
)
select * from jsonFolders;