我正在尝试对默认的ASP.NET RoleProvider实施以下调整,以便它支持分层角色定义。但是我无法创建以下函数,它会保留Executing the function
...
参考:http://mark.tremaine.net/howto/hierarchical-sql-role-provider/
这个功能出了什么问题?
-- ================================================
-- Template generated from Template Explorer using:
-- Create Multi-Statement Function (New Menu).SQL
--
-- Use the Specify Values for Template Parameters
-- command (Ctrl-Shift-M) to fill in the parameter
-- values below.
--
-- This block of comments will not be included in
-- the definition of the function.
-- ================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE FUNCTION [dbo].[aspnet_Roles_Ancestor_TVF] (
@RoleId uniqueidentifier
)
RETURNS
@aspnet_Roles TABLE (
ApplicationId uniqueidentifier
, RoleId uniqueidentifier
, RoleName nvarchar(256)
, LoweredRoleName nvarchar(256)
, Description nvarchar(256)
, ParentRoleId uniqueidentifier
)
AS
BEGIN
; WITH aspnet_Roles_CTE (
ApplicationId
, RoleId
, RoleName
, LoweredRoleName
, Description
, ParentRoleId
, HierarchyLevel
) AS (
SELECT
ApplicationId
, RoleId
, RoleName
, LoweredRoleName
, Description
, ParentRoleId
, 1 AS HierarchyLevel
FROM aspnet_Roles
WHERE RoleId = @RoleId
UNION ALL
SELECT
aspnet_Roles.ApplicationId
, aspnet_Roles.RoleId
, aspnet_Roles.RoleName
, aspnet_Roles.LoweredRoleName
, aspnet_Roles.Description
, aspnet_Roles.ParentRoleId
, aspnet_Roles_CTE.HierarchyLevel + 1 AS HierarchyLevel
FROM aspnet_Roles
INNER JOIN aspnet_Roles_CTE
ON aspnet_Roles.RoleId = aspnet_Roles_CTE.ParentRoleId
)
INSERT INTO @aspnet_Roles (
ApplicationId
, RoleId
, RoleName
, LoweredRoleName
, Description
, ParentRoleId
)
SELECT
ApplicationId
, RoleId
, RoleName
, LoweredRoleName
, Description
, ParentRoleId
FROM aspnet_Roles_CTE
ORDER BY HierarchyLevel
RETURN
END
GO
答案 0 :(得分:1)
我认为问题出在你的CTE结构中。 Union查询的前半部分应代表父级,第二部分应返回子级。也就是说,你走在层次结构中而不是它。因此,我会将Union查询的后半部分中的On子句更改为:
aspnet_Roles_CTE.RoleId = aspnet_Roles.ParentRoleId
。
修改强>
一些示例数据会有所帮助。这是我掀起的一个小测试:
Declare @RoleId int;
Set @RoleId = 1;
With aspnet_Roles As
(
Select 1 As ApplicationId, 1 As RoleId, 'Parent Role A' As RoleName, Null As ParentRoleId
Union All Select 1, 2, 'Parent Role B', Null
Union All Select 1, 3, 'Parent Role C', Null
Union All Select 1, 4, 'Child Role A-A', 1
Union All Select 1, 5, 'Child Role A-B', 1
Union All Select 1, 6, 'Child Role A-C', 1
Union All Select 1, 7, 'Child Role A-A-A', 4
Union All Select 1, 8, 'Child Role A-A-B', 4
Union All Select 1, 9, 'Child Role A-A-C', 4
)
, aspnet_Roles_CTE ( ApplicationId, RoleId, RoleName, ParentRoleId, HierarchyLevel ) As
(
Select ApplicationId, RoleId, RoleName, ParentRoleId, 1 AS HierarchyLevel
From aspnet_Roles
Where RoleId = @RoleId
Union All
Select AR.ApplicationId, AR.RoleId, AR.RoleName, AR.ParentRoleId, HierarchyLevel + 1
From aspnet_Roles As AR
Join aspnet_Roles_CTE As CTE
On CTE.ApplicationId = AR.ApplicationId
And CTE.RoleId = AR.ParentRoleId
)
Select ApplicationId, RoleId, RoleName, ParentRoleId, HierarchyLevel
From aspnet_Roles_CTE
结果:
ApplicationId | RoleId | RoleName | ParentRoleId | HierarchyLevel 1 | 1 | Parent Role A | NULL | 1 1 | 4 | Child Role A-A | 1 | 2 1 | 5 | Child Role A-B | 1 | 2 1 | 6 | Child Role A-C | 1 | 2 1 | 7 | Child Role A-A-A | 4 | 3 1 | 8 | Child Role A-A-B | 4 | 3 1 | 9 | Child Role A-A-C | 4 | 3
答案 1 :(得分:0)
我知道CTE有一个递归耗尽限制,但也许你有一个孩子的父母的孩子,即一个循环关系?