2012-11-03 4 views
1

moduleid, name, parent_id의 3 개의 열이있는 tblmodules라는 테이블이 있습니다. parent_id 열은 다른 모듈의 값을 취합니다. 예 :Sql은 while 루프에서 이름과 부모를 가져옵니다.

Moduleid  Name  Parentid 
--------  -----  -------- 
1   grandparent Null 
2   parent   1 
3   child   2 

수준을 부여하는 하위의 부모 ID와 이름을 사용하는 저장 프로 시저를 원합니다. 그래서 나는 다음과 같은 것을 개발한다.

 @moduleid bigint, 
    @level int 

AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    declare @parentid bigint 
    declare @name nvarchar(100) 
    set @parentid = (select parentid from tblModules where ModuleId = @moduleid) 


    declare @counter int 
    set @counter = 1 

    while @counter < @level 
    begin 

     set @parentid = (select parentid from tblModules where ModuleId = @parentid) 
     set @name = (select Name from tblModules where ModuleId = @parentid) 

     set @counter = @counter + 1 
    end 

    select @parentid AS ID 
    select @name as Name 

end 

절차가 정상적으로 작동하고 부모의 올바른 ID를 가져 오지만 이름은 자식과 동일하게 유지됩니다. 예를 들어, @moduleid : 3 및 @level : 2 값을주는 실행 중입니다. 결과 ID : 1이 올바르지 만 조부모 대신 이름 : 아동이 나타납니다. 어떤 도움이 필요합니까? 내 스크립트에서

+0

에 대한 CTE를 사용하는 당신이에 CTE (공통 테이블 식)를 사용할 수 있다고 생각 대본. ModuleID 2의 예상 출력은 얼마입니까? – TechDo

답변

2

나는 그들의 ParentLevel (@level)에 가입 할 수준의 발견 모듈

CREATE PROCEDURE dbo.ParentLevelName 
(
    @moduleid bigint, 
    @level int 
) 
AS 
BEGIN 
    SET NOCOUNT ON; 

    ;WITH ParentTree(Parentid, Moduleid, Name, ParentLevel) 
    AS 
    (
    SELECT Parentid, Moduleid, Name, 0 AS ParentLevel 
    FROM tblmodules 
    WHERE Parentid IS NULL 
    UNION ALL 
    SELECT t.Parentid, t.Moduleid, t.Name, p.ParentLevel + 1 
    FROM tblmodules t JOIN ParentTree p ON t.Parentid = p.Moduleid 
    ) 
    SELECT p.Parentid, p.Moduleid, p.Name, p2.Name PerantLevelName 
    FROM ParentTree p LEFT JOIN ParentTree p2 ON p.ParentLevel - @level = p2.ParentLevel 
    WHERE p.Moduleid = @moduleid 
END 

데모 SQL Fiddle

관련 문제