创建用户定义的函数,以返回为json的层次数据

发布于 2025-01-23 11:46:34 字数 3399 浏览 1 评论 0原文

这是一个问题的一部分。我有部门表,使用 hierarchyId 存储层次数据。

IDHIEARARCHYID名称
1/MHz
2/2/Finance
3/3/IT
4/3/4/软件开发
5/3/5/QA
6/2/6/counctats

我想将此表作为json < /code>对于我的 treeview 在前侧。

我做了什么:

CREATE FUNCTION dbo.GetDepartmentAsJson
    (@departmentId hierarchyid, 
     @IsRoot int)
RETURNS nvarchar(max)
AS
BEGIN
    DECLARE @Json NVARCHAR(MAX) = '{}',
            @Id int,
            @Name varchar(50),
            @Children NVARCHAR(MAX) = '{}',
            @Hierar Hierarchyid

    SET @Json = (SELECT 
                     t.Id, t.HierarchyId, t.Name,
                     children = JSON_QUERY(dbo.GetDepartmentAsJson(t.HierarchyId, 2))
                 FROM Departments t
                 WHERE t.HierarchyId <> @departmentId
                   AND t.HierarchyId.IsDescendantOf(@departmentId) = 1
                 FOR JSON PATH);

    IF (@IsRoot = 1) 
    BEGIN
        SELECT
            @Id = t.Id,
            @Hierar = t.HierarchyId,
            @Name = t.Name
        FROM 
            Departments t
        WHERE 
            t.HierarchyId = @departmentId;

        SET @Json = 
        '{"Id":"' + CONVERT(varchar(7), @Id) +
        '","HierarchyId":"' + @Hierar.ToString() + 
        '","Name":"' + @Name + 
        '","Children":' + CAST(@Json AS NVARCHAR(MAX)) + '}';
        SET @IsRoot = 2;
    END

    RETURN @Json;
END;

结果:

 {
  "Id": "1",
  "HierarchyId": "/",
  "Name": "MHz",
  "Children": [
    {
      "Id": 2,
      "HierarchyId": "/2/",
      "Name": "Finance",
      "Children": [
        {
          "Id": 6,
          "HierarchyId": "/2/6/",
          "Name": "Accountant"
        }
      ]
    },
    /* This should not be listed because already included as a child in Finance */
    {
      "Id": 6,
      "HierarchyId": "/2/6/",
      "Name": "Accountant"
    },
    {
      "Id": 3,
      "HierarchyId": "/3/",
      "Name": "IT",
      "Children": [
        {
          "Id": 4,
          "HierarchyId": "/3/4/",
          "Name": "Software Development"
        },
        {
          "Id": 5,
          "HierarchyId": "/3/5/",
          "Name": "QA"
        }
      ]
    },
    /* They both should not be listed because already included as a child in IT */
    {
      "Id": 4,
      "HierarchyId": "/3/4/",
      "Name": "Software Development"
    },
    {
      "Id": 5,
      "HierarchyId": "/3/5/",
      "Name": "QA"
    }
  ]
}

如何排除在父元素中列出的孩子元素?

This is a part of this question . I have Departments table which uses HierarchyId to store hierarchical data.

IdHieararchyIdName
1/MHz
2/2/Finance
3/3/IT
4/3/4/Software Development
5/3/5/QA
6/2/6/Accountant

I want to get this table as JSON for my TreeView on front side.

What I did:

CREATE FUNCTION dbo.GetDepartmentAsJson
    (@departmentId hierarchyid, 
     @IsRoot int)
RETURNS nvarchar(max)
AS
BEGIN
    DECLARE @Json NVARCHAR(MAX) = '{}',
            @Id int,
            @Name varchar(50),
            @Children NVARCHAR(MAX) = '{}',
            @Hierar Hierarchyid

    SET @Json = (SELECT 
                     t.Id, t.HierarchyId, t.Name,
                     children = JSON_QUERY(dbo.GetDepartmentAsJson(t.HierarchyId, 2))
                 FROM Departments t
                 WHERE t.HierarchyId <> @departmentId
                   AND t.HierarchyId.IsDescendantOf(@departmentId) = 1
                 FOR JSON PATH);

    IF (@IsRoot = 1) 
    BEGIN
        SELECT
            @Id = t.Id,
            @Hierar = t.HierarchyId,
            @Name = t.Name
        FROM 
            Departments t
        WHERE 
            t.HierarchyId = @departmentId;

        SET @Json = 
        '{"Id":"' + CONVERT(varchar(7), @Id) +
        '","HierarchyId":"' + @Hierar.ToString() + 
        '","Name":"' + @Name + 
        '","Children":' + CAST(@Json AS NVARCHAR(MAX)) + '}';
        SET @IsRoot = 2;
    END

    RETURN @Json;
END;

Result:

 {
  "Id": "1",
  "HierarchyId": "/",
  "Name": "MHz",
  "Children": [
    {
      "Id": 2,
      "HierarchyId": "/2/",
      "Name": "Finance",
      "Children": [
        {
          "Id": 6,
          "HierarchyId": "/2/6/",
          "Name": "Accountant"
        }
      ]
    },
    /* This should not be listed because already included as a child in Finance */
    {
      "Id": 6,
      "HierarchyId": "/2/6/",
      "Name": "Accountant"
    },
    {
      "Id": 3,
      "HierarchyId": "/3/",
      "Name": "IT",
      "Children": [
        {
          "Id": 4,
          "HierarchyId": "/3/4/",
          "Name": "Software Development"
        },
        {
          "Id": 5,
          "HierarchyId": "/3/5/",
          "Name": "QA"
        }
      ]
    },
    /* They both should not be listed because already included as a child in IT */
    {
      "Id": 4,
      "HierarchyId": "/3/4/",
      "Name": "Software Development"
    },
    {
      "Id": 5,
      "HierarchyId": "/3/5/",
      "Name": "QA"
    }
  ]
}

How can I exclude this child elements which have been already listed in parent element?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

穿越时光隧道 2025-01-30 11:46:35

您应该检查后代的水平以及

CREATE FUNCTION dbo.GetDepartmentAsJson(@departmentId hierarchyid, @level int)
RETURNS nvarchar(max)
AS
BEGIN
DECLARE @Json NVARCHAR(MAX) = '{}',
    @Id int,
    @Name varchar(50),
    @Childeren NVARCHAR(MAX) = '{}',
    @Hierar Hierarchyid

    SET @Json = (SELECT
    t.Id,
    t.HierarchyId,
    t.Name,
    children = JSON_QUERY(dbo.GetDepartmentAsJson(t.HierarchyId, @level + 1))
    FROM Departments t
    WHERE t.HierarchyId <> @departmentId
    AND t.HierarchyId.IsDescendantOf(@departmentId) = 1 and t.HierarchyId.GetLevel() =  @level + 1
    FOR JSON PATH);

    IF(@level = 0) 
    BEGIN
        SELECT
        @Id = t.Id,
        @Hierar = t.HierarchyId,
        @Name = t.Name
        FROM Departments t
        WHERE t.HierarchyId = @departmentId;

        SET @Json = 
        '{"Id":"' + CONVERT(varchar(7), @Id) +
        '","HierarchyId":"' + @Hierar.ToString() + 
        '","Name":"' + @Name + 
        '","Children":' + CAST(@Json AS NVARCHAR(MAX)) + '}';
    END

    return @Json;

  END;

层次结构的根为0 ,因此选择dbo.getDepartmentAsjson('/',0)

db&lt;&gt;&gt;&gt; fiddle

You should check the level of the descendant as well

CREATE FUNCTION dbo.GetDepartmentAsJson(@departmentId hierarchyid, @level int)
RETURNS nvarchar(max)
AS
BEGIN
DECLARE @Json NVARCHAR(MAX) = '{}',
    @Id int,
    @Name varchar(50),
    @Childeren NVARCHAR(MAX) = '{}',
    @Hierar Hierarchyid

    SET @Json = (SELECT
    t.Id,
    t.HierarchyId,
    t.Name,
    children = JSON_QUERY(dbo.GetDepartmentAsJson(t.HierarchyId, @level + 1))
    FROM Departments t
    WHERE t.HierarchyId <> @departmentId
    AND t.HierarchyId.IsDescendantOf(@departmentId) = 1 and t.HierarchyId.GetLevel() =  @level + 1
    FOR JSON PATH);

    IF(@level = 0) 
    BEGIN
        SELECT
        @Id = t.Id,
        @Hierar = t.HierarchyId,
        @Name = t.Name
        FROM Departments t
        WHERE t.HierarchyId = @departmentId;

        SET @Json = 
        '{"Id":"' + CONVERT(varchar(7), @Id) +
        '","HierarchyId":"' + @Hierar.ToString() + 
        '","Name":"' + @Name + 
        '","Children":' + CAST(@Json AS NVARCHAR(MAX)) + '}';
    END

    return @Json;

  END;

The root of the hierarchy is level 0, so select dbo.GetDepartmentAsJson ('/', 0)

db<>fiddle

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文