Генерация HierarchyID - PullRequest
       7

Генерация HierarchyID

8 голосов
/ 14 декабря 2010

Я хотел бы добавить иерархию, как это

/ - CEO (Root)

/ 1 / - Менеджер по закупкам / 2 / - Менеджер по продажам

/ 1/1 / - Менеджер по закупкам / 2/1 / - Руководитель продаж

Это та иерархия, которую я хотел бы использовать, правильная ли, если да, то как я могу это сделать, может ли кто-нибудь дать мне фрагмент кода.

Ответы [ 2 ]

17 голосов
/ 15 сентября 2011

Я столкнулся с этим вопросом, когда искал информацию о типе данных hierarchyid, и подумал, что кому-нибудь еще, идущему за мной, будет интересно увидеть код для вставки hierarchyid s в соответствии с вопросом.

Я не утверждаю, что это единственные способы ввода hierarchyid s, но, надеюсь, это поможет тем, кто, как и я, не имел опыта работы с этим типом данных.

Используя эту таблицу,

create table OrgChart
(
    Position hierarchyid,
    Title nvarchar(50)
)

Вы можете использовать Parse для прямой вставки hierarchyid с использованием строковых путей:

insert into OrgChart(Position, Title) 
    values  (hierarchyid::Parse('/'), 'CEO'),
            (hierarchyid::Parse('/1/'), 'Purchase Manager'),
            (hierarchyid::Parse('/1/1/'), 'Purchase Executive'),
            (hierarchyid::Parse('/2/'), 'Sales Manager'),
            (hierarchyid::Parse('/2/1/'), 'Sales Executive')

и используйте следующий запрос для проверки таблицы

select Position.ToString(), * from OrgChart

Вы также можете использовать hierarchyid методы типа данных GetRoot и GetDescendant для построения иерархии. Я нашел этот метод более громоздким, но я полагаю, что использование этих методов необходимо, если вы программно управляете иерархией.

declare @root hierarchyid,
        @id hierarchyid

set @root = hierarchyid::GetRoot()

insert into OrgChart(Position, Title) values (@root, 'CEO')

set @id = @root.GetDescendant(null, null)
insert into OrgChart(Position, Title) values (@id, 'Purchase Manager')

set @id = @root.GetDescendant(@id, null)
insert into OrgChart(Position, Title) values (@id, 'Sales Manager')

select @id = Position.GetDescendant(null, null) from OrgChart where Title = 'Purchase Manager'    
insert into OrgChart(Position, Title) values (@id, 'Purchase Executive')

select @id = Position.GetDescendant(null, null) from OrgChart where Title = 'Sales Manager'    
insert into OrgChart(Position, Title) values (@id, 'Sales Executive')

Обязательно ознакомьтесь с ссылками, приведенными в другом ответе, но, надеюсь, этот код тоже поможет.

0 голосов
/ 15 сентября 2017

Предположим, что у вас есть схема таблицы с самосоединением (как показано ниже) и что ManagerID вашего генерального директора равен NULL.

CREATE TABLE Employees
(
    EmployeeID int NOT NULL IDENTITY(1,1) PRIMARY KEY
    , JobTitle nvarchar(50) NOT NULL
    , FirstName nvarchar(50) NOT NULL
    , LastName nvarchar(50)
    , ManagerID int
) 

ALTER TABLE dbo.Employee ADD CONSTRAINT FK_Employee_ManagingEmployee FOREIGN KEY (MangerID) REFERENCES dbo.Employee (EmployeeID) ON

UPDATE NO ACTION
    ON

DELETE NO ACTION

Вы можете автоматически сгенерировать начальный набор значений иерархии.используя следующий рекурсивный CTE:

;WITH EmployeeHierarchy (
    EmployeeHierarchyID
    , EmployeeID
    , JobTitle
    , LastName
    , FirstName
    , ManagerID
    )
AS (
    SELECT HIERARCHYID::GetRoot() AS EmployeeHierarchyID
        , EmployeeID
        , JobTitle
        , LastName
        , FirstName
        , ManagerID
    FROM Employee
    WHERE ManagerID IS NULL

    UNION ALL

    SELECT HIERARCHYID::Parse(EmployeeHierarchyID.ToString() + (
                CONVERT(VARCHAR(20), ROW_NUMBER() OVER (
                        ORDER BY EmployeeHierarchy.EmployeeID
                        ))
                ) + '/') AS EmployeeHierarchy
        , EmployeeHierarchy.EmployeeID
        , EmployeeHierarchy.JobTitle
        , EmployeeHierarchy.LastName
        , EmployeeHierarchy.FirstName
        , EmployeeHierarchy.ManagerID
    FROM Employee
    INNER JOIN EmployeeHierarchy AS d
        ON Employee.ManagerID = d.EmployeeID
    )
SELECT TOP (100) PERCENT EmployeeHierarchyID
    , EmployeeID
    , JobTitle
    , LastName
    , FirstName
    , ManagerID
INTO #EmployeeHierarchy
FROM EmployeeHierarchy
ORDER BY EmployeeHierarchyID

Тогда становится довольно тривиальным вопросом добавить столбец иерархии в таблицу, добавить индекс к нему, а затем заполнить его, присоединившись к временной таблице.

UPDATE Employee
SET          EmployeeHierarchyID = #EmployeeHierarchy.EmployeeHierarchyID
FROM     Employee INNER JOIN
                  #EmployeeHierachy ON Employee.EmployeeID = #EmployeeHierarchy.EmployeeID

Однако имейте в виду, что если вы хотите, чтобы данные иерархии оставались непротиворечивыми после добавления, есть очень конкретные способы их сохранения.

...