2014-10-13 2 views
1

Itzik Ben-Gan은 여기에 몇 가지 간단한 방법으로 hierarchyId 데이터 형식을 사용하는 방법을 설명했습니다.SQL Server HierarchyID : 여러 자식을 추가하는 방법?

http://sqlmag.com/t-sql/hierarchyid

그는이 같은이 시저를 호출 할 필요가 트리에 모든 잎을 추가하려면 어떤 루트

-- Web Listing 2: Script to Create Stored Procedure usp_AddEmp 
IF OBJECT_ID('dbo.usp_AddEmp', 'P') IS NOT NULL 
    DROP PROC dbo.usp_AddEmp; 
GO 
CREATE PROC dbo.usp_AddEmp 
    @empid AS INT, 
    @mgrid AS INT = NULL, 
    @empname AS VARCHAR(25), 
    @salary AS MONEY 
AS 

DECLARE 
    @hid   AS HIERARCHYID, 
    @mgr_hid  AS HIERARCHYID, 
    @last_child_hid AS HIERARCHYID; 

IF @mgrid IS NULL 
    SET @hid = HIERARCHYID::GetRoot(); 
ELSE 
BEGIN 
    SET @mgr_hid = (SELECT hid FROM dbo.Employees WHERE empid = @mgrid); 
    SET @last_child_hid = 
    (SELECT MAX(hid) FROM dbo.Employees 
    WHERE hid.GetAncestor(1) = @mgr_hid); 
    SET @hid = @mgr_hid.GetDescendant(@last_child_hid, NULL); 
END 

INSERT INTO dbo.Employees(empid, hid, empname, salary) 
    VALUES(@empid, @hid, @empname, @salary); 
GO 

에 아이를 추가 할 저장된 프로 시저를 사용

EXEC dbo.usp_AddEmp 
    @empid = 1, @mgrid = NULL, @empname = 'David' , @salary = $10000.00; 
EXEC dbo.usp_AddEmp 
    @empid = 2, @mgrid = 1, @empname = 'Eitan' , @salary = $7000.00; 
EXEC dbo.usp_AddEmp 
    @empid = 3, @mgrid = 1, @empname = 'Ina' , @salary = $7500.00; 
EXEC dbo.usp_AddEmp 
    @empid = 4, @mgrid = 2, @empname = 'Seraph' , @salary = $5000.00; 
EXEC dbo.usp_AddEmp 
    @empid = 5, @mgrid = 2, @empname = 'Jiru' , @salary = $5500.00; 
EXEC dbo.usp_AddEmp 
    @empid = 6, @mgrid = 2, @empname = 'Steve' , @salary = $4500.00; 
EXEC dbo.usp_AddEmp 
    @empid = 7, @mgrid = 3, @empname = 'Aaron' , @salary = $5000.00; 
EXEC dbo.usp_AddEmp 
    @empid = 8, @mgrid = 5, @empname = 'Lilach' , @salary = $3500.00; 
EXEC dbo.usp_AddEmp 
    @empid = 9, @mgrid = 7, @empname = 'Rita' , @salary = $3000.00; 
EXEC dbo.usp_AddEmp 
    @empid = 10, @mgrid = 5, @empname = 'Sean' , @salary = $3000.00; 
EXEC dbo.usp_AddEmp 
    @empid = 11, @mgrid = 7, @empname = 'Gabriel', @salary = $3000.00; 
EXEC dbo.usp_AddEmp 
    @empid = 12, @mgrid = 9, @empname = 'Emilia' , @salary = $2000.00; 
EXEC dbo.usp_AddEmp 
    @empid = 13, @mgrid = 9, @empname = 'Michael', @salary = $2000.00; 
EXEC dbo.usp_AddEmp 
    @empid = 14, @mgrid = 9, @empname = 'Didi' , @salary = $1500.00; 

내 질문을 is :

나는 잎 형제 목록이있는 테이블을 가지고있다. h 부모님에게 같은 레벨로 추가해야합니다

declare @toadd table 
(
    empid INT, 
    mgrid INT, 
    empname VARCHAR(25), 
    salary MONEY 
) 

insert into @toadd(empid, mgrid, empname, salary) 
select 15, 14, 'Itzik', $0.01 
union all 
select 16, 14, 'Jack', $0.02 
union all 
select 17, 14, 'Alex', $0.03 
union all 
select 18, 14, 'Mary', $0.04 
union all 
select 19, 14, 'John', $0.05 

커서를 생성하고 proc을 N 번 호출 할 수 있습니다. 아마 더 효과적 일 수 있습니까? 어떻게 든 하나의 쿼리?

답변

3

'/ [int /] [... n]'형식의 문자열이 HierarchyId로 올바르게 변환된다는 사실을 사용할 수 있습니다. 따라서 GetDescendant를 사용하여 관리자에게 부하 직원을 추가하는 대신 관리자의 HierarchyId를 가져 와서 ToString()을 호출하고 '{EmpId} /'를 붙인 다음 HierarchyId로 캐스팅합니다. 열은 이미 이러한 유형의이다 특히 :.이 모든 사람의 숨겨 값이 형태 "/ EMPID/{관리자의 HID)"에 있다고 가정

with emps_and_mgrs as (
    select *, m.hid as mhid 
    from @toadd as t 
    cross apply (
     select hid 
     from dbo.Employees 
     where empid= t.mgrid 
    ) as m 
) 

INSERT INTO dbo.Employees(empid, hid, empname, salary) 
select empid, mhid.ToString() + cast(empid as varchar) + '/', empname, salary 
from emps_and_mgrs; 

. 여기에는 원래 예제에서 David가 포함됩니다. GetRoot() (즉 "/")의 값을 가지기보다는 "/ 1 /"의 값을가집니다. 또한이 전략을 채택하려는 경우 관리자의 empid도 저장해야합니다. 이렇게하면, empid와 manager의 empid를 사용하는 재귀 적 cte를 작성하여 무언가가 옆으로 가면 모든 HierarchyIds를 다시 생성 할 수 있습니다.

+0

Thanx Ben, 내 실제 db에 테이블에 parent_id라는 ID를 저장합니다. – Oleg

+0

하지만 14를 5로 대체하면 어떨까요? 나는. 5에는 이미 어린이가 있으며 기존의 "형제"에게이 새로운 5 개를 추가해야합니다. – Oleg

+0

문제가되지 않습니다. EmpId는 고유하므로 각 계층 구조는 고유합니다. 예를 들어, EmpId = 15 인 레코드는 계층/1/2/5/15 /를 가질 것이고 EmpId = 16은 1/1/2/5/16/을 가질 것입니다. EmpId = 8에 대한 기존 행은 다른 행렬과 구별되는/1/2/5/8 /을 갖습니다. –

관련 문제