为返回为 JSON 的分层数据创建用户定义函数
Create user defined function for Hierarchical data returning as JSON
这是. I have Departments
table which uses HierarchyId
存储分层数据。
Id
HieararchyId
Name
1
/
MHz
2
/2/
Finance
3
/3/
IT
4
/3/4/
Software Development
5
/3/5/
QA
6
/2/6/
Accountant
我想把这个 table 作为我的 TreeView 在前面的 JSON
。
我做了什么:
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"
}
]
}
如何排除已在父元素中列出的子元素?
你也应该检查后代的等级
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,所以select dbo.GetDepartmentAsJson ('/', 0)
这是Departments
table which uses HierarchyId
存储分层数据。
Id | HieararchyId | Name |
---|---|---|
1 | / | MHz |
2 | /2/ | Finance |
3 | /3/ | IT |
4 | /3/4/ | Software Development |
5 | /3/5/ | QA |
6 | /2/6/ | Accountant |
我想把这个 table 作为我的 TreeView 在前面的 JSON
。
我做了什么:
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"
}
]
}
如何排除已在父元素中列出的子元素?
你也应该检查后代的等级
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,所以select dbo.GetDepartmentAsJson ('/', 0)