创建用户定义的函数,以返回为json的层次数据
这是一个问题的一部分。我有部门
表,使用 hierarchyId
存储层次数据。
ID | HIEARARCHYID | 名称 |
---|---|---|
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.
Id | HieararchyId | Name |
---|---|---|
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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您应该检查后代的水平以及
层次结构的根为0 ,因此
选择dbo.getDepartmentAsjson('/',0)
db&lt;&gt;&gt;&gt; fiddle
You should check the level of the descendant as well
The root of the hierarchy is level 0, so
select dbo.GetDepartmentAsJson ('/', 0)
db<>fiddle