1

私は次の再帰関数を持っています:

ALTER FUNCTION [dbo].[ListAncestors] 
(   
    @Id int
)   
RETURNS TABLE  
As  
RETURN  
(   
    WITH cte As  
    (   
        SELECT
            UserId,
            ManagerId,  
            Forename,
            Surname  
        FROM  
            dbo.Users   
        WHERE  
            UserId = @Id   

        UNION ALL  

        SELECT  
            T.UserID,
            T.ManagerID,  
            T.Forename,   
            T.Surname  
        FROM  
            cte As C INNER JOIN dbo.Users As T   
            ON C.UserID = T.ManagerID   
    )   
    SELECT
        Forename,
   Surname 
    FROM  
        cte
);

基本的には、指定されたユーザーの下にあるすべてのユーザーの名前を(IDに基づいて)返します。私がやりたいのは、この関数を変更して、特定のuserIDが別のuserIDの祖先であるかどうかをチェックする別の関数を作成することです。

署名は次のようになると思います。

CREATE FUNCTION IsAncestor(@Id int, @AncestorId int) RETURNS BIT
4

2 に答える 2

1

どうですか:

WHILE @Id IS NOT NULL AND @Id <> @AncestorId
BEGIN
 SET @Id = (
  SELECT ManagerId FROM dbo.Users WHERE UserId = @Id
 )
END

RETURN CASE WHEN @Id IS NOT NULL THEN 1 ELSE 0 END
于 2010-08-01T11:01:04.353 に答える
1

最初のCTEがIDを受け取り、そのIDのすべての「祖先」をリストすることを受け入れる場合、次のクエリはこの関係をテストすると思います。

WITH cte As  
(   
    SELECT
        UserId,
        Forename,
        Surname  
    FROM  
        dbo.Users   
    WHERE  
        UserId = @Id   

    UNION ALL  

    SELECT  
        T.UserID,  
        T.Forename,   
        T.Surname  
    FROM  
        cte As C INNER JOIN dbo.Users As T   
        ON C.UserID = T.ManagerID and C.UserID <> @ancestorID
)   
SELECT CAST (COUNT(*) as BIT) FROM cte WHERE UserID = @ancestorID

最初の機能を考えると、人は自分自身と「祖先」の関係にあるので、それは少し奇妙です。

ちなみに、必要がないので、CTEのselectステートメントからManagerIDを削除しました

于 2010-08-01T12:15:21.157 に答える