2010-12-14 25 views
8

Vorrei inserire il hierarchyid come questoGenerazione hierarchyid

/- CEO (Root)

/1/- Responsabile Acquisti /2/- Sales Manager

/1/1/- Executive acquisti /2/1/- Responsabile vendite

Questo è ciò che la gerarchia vorrei utilizzare, è giusto uno, se sì, come posso fare questo, qualcuno può darmi qualche frammento di codice.

+0

Controllare questi URL: [Utilizzo dei tipi di dati gerarchici (Motore di database)] (http://technet.microsoft.com/en-us/library/bb677173.aspx) [Esercitazione: Utilizzo del tipo di dati gerarchico] (http: //technet.microsoft.com/en-us/library/bb677213.aspx) –

risposta

17

Mi sono imbattuto in questa domanda durante la ricerca di informazioni sul tipo di dati hierarchyid e ho pensato che sarebbe stato interessante per chiunque altro venisse dopo di me per vedere anche il codice per inserire hierarchyid s come da domanda.

Non ho la pretesa che questi sono gli unici modi per inserire hierarchyid s, ma speriamo che aiutare coloro che, come me, non hanno precedenti esperienze di lavoro con questo tipo di dati.

Utilizzando questa tabella,

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

è possibile utilizzare Parse per inserire direttamente le hierarchyid s utilizzando i percorsi a corda:

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') 

e utilizzare la seguente query per controllare la tabella

select Position.ToString(), * from OrgChart 

È inoltre possibile utilizzare il hierarchyid metodi tipo di dati GetRoot e GetDescendant per costruire la gerarchia. Ho trovato questo metodo più ingombrante, ma suppongo che l'utilizzo di questi metodi sia necessario se gestisci la gerarchia in modo programmatico.

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') 

Sicuramente controllare i link forniti in altra risposta, ma si spera che avendo questo codice per provare aiuterà pure.

+0

Risposta piacevole. Grazie per averlo semplificato. – Phil

+0

@adrift il tuo primo codice INSERT presume che tu conosca il percorso della gerarchia prima della mano e quindi non sia molto mantenibile in uno scenario di mondo reale. Dovresti usare i metodi gerarchici (quelli che hai etichettato come ingombranti) per quello. –

0

Supponiamo di avere uno schema di tabella con un self-join (come mostrato di seguito) e che il ManagerID del CEO è 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 

È possibile generare automaticamente una serie iniziale di valori hierarchyid utilizzando il seguente CTE ricorsiva:

;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 

Diventa allora una questione abbastanza banale per aggiungere una colonna hierarchyid alla tabella, aggiungere un indice su di esso e quindi popolarlo collegandosi alla tabella temporanea.

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

Tuttavia, tenere presente che se si desidera che i dati hierarchyid di rimanere coerente dopo aver aggiunto, ci sono modi molto specifici in cui dovrebbe essere mantenuto.

+0

Ecco un altro esempio per la generazione Hid quando hai già colonne Id-ParentId https://www.codeproject.com/Articles/1192607/Combination-of-Id-ParentId-and-HierarchyId –