/*[테이블설계]*/
CREATE TABLE TreeMenu(
menu_cd int , --메뉴코드
menu_nm varchar(50) , --메뉴명
parent_cd int , --상위메뉴코드
CONSTRAINT PK_TreeMenu PRIMARY KEY (menu_cd)
)
/*[샘플데이터]*/insert into TreeMenu VALUES(1, '시작' , 0)
insert into TreeMenu VALUES(2, '프로그램' , 1)
insert into TreeMenu VALUES(3, '설정' , 1)
insert into TreeMenu VALUES(4, '보조프로그램', 2)
insert into TreeMenu VALUES(5, '제어판' , 3)
insert into TreeMenu VALUES(6, '네트워크환경', 5)
insert into TreeMenu VALUES(7, '계산기' , 4)
insert into TreeMenu VALUES(8, '그림판' , 4)
GO
/*[핵심함수 구현]*/
/***********************************************
트리구조에서
각 노드(행)의 절대위치를 Binary계산하는 함수
최대 64 Level 지원
***********************************************/
go
CREATE FUNCTION FN_TreeOrderBy(
@root int, /*루트값*/
@menu_cd int /*현재값*/
) RETURNS varbinary(256)
BEGIN
DECLARE @parent_cd int ,
@level_bin varbinary(256)
IF @menu_cd = @root
BEGIN
RETURN 0
END
select @level_bin = CAST(@menu_cd AS varbinary(4)) --값 초기화
/*루프로 menu_cd위 절대위치 계산*/
WHILE 1 = 1
BEGIN
SELECT @parent_cd = parent_cd
FROM TreeMenu WITH(NOLOCK)
WHERE menu_cd = @menu_cd
IF (@root=@parent_cd or @parent_cd=0 or @parent_cd is null)
BEGIN
BREAK
END
SELECT @menu_cd = @parent_cd
SELECT @level_bin = CAST(@parent_cd AS varbinary(4)) + @level_bin
END
RETURN @level_bin
END
go
/*[함수사용하여 조회]*/
SELECT a.* ,
dbo.FN_TreeOrderBy(1, a.menu_cd) absolute_pos
FROM TreeMenu A WITH(NOLOCK)
ORDER BY absolute_pos --계산된 열로 정열
/*
속도를 더 빨리 하기 위한 방법으로는 삭제/수정/등록시
절대위치(absolute_pos)를 계산해서 저장하는 방법입니다. 저장된 절대위치에 클러스트인덱스 설정하면 검색속도가 더욱 빠릅니다
그래도 대용량 쿼리할 때 이용하기엔 쫌 부담이 되겠네요 -ㅅ-
*/
Posted by 좐군


