2011-03-18 18 views
6

Tengo un problema con hierarchyID y UserRights para un menú. Solo quiero dar al Usuario el Derecho para el Nivel 4, por ejemplo, y mi QUery debe seleccionar automáticamente a todos los Padres del Niño de Nivel 4. ¿Cómo hacer esto?HierarchyID Cómo obtener todos los elementos principales de un hijo

¿Entiende mi problema? Simplemente quiero a todos los Padres (ancestros) de un niño.

Saluda Manuel

+0

Esta cuestión también ha sido respondida aquí, y tiene un enfoque bastante interesante sugerido por Simon Ince. http://stackoverflow.com/questions/3119860/how-do-you-get-all-ancestors-of-a-node-using-sql-server-2008-hierarchyid Cheers, – Eric

+0

Deberías dar las columnas de la tabla con algunos datos de muestra y luego proporcione lo que desea lograr como resultado. Ayudaría a las personas a dar mejores respuestas. Además, si ya ha intentado algo, debe dar el código SQL. – JamieSee

Respuesta

1

supongamos que tiene esta tabla:

CREATE TABLE Hierarchy 
(
    CompanyNode hierarchyid NOT NULL, 
    CompanyId int NOT NULL, 
    NodeLevel AS CompanyNode.GetLevel() 
    CONSTRAINT PK_Hierarchy PRIMARY KEY NONCLUSTERED (CompanyNode) 
) 

y se rellenan de él para que mantenga estos datos:

CompanyNode CompanyId NodeLevel 
0x 1 0 
0x58 2 1 
0x5AC0 3 2 
0x68 100 1 
0x6AC0 101 2 
0x6AD6 1000 3 
0x6AD6B0 10000 4 
0x78 20 1 
0x7AC0 200 2 
0x7AD6 2000 3 
0x7AD6B0 20000 4 
0x7AD6B580 200000 5 
0x7AD6D0 20001 4 
0x7ADA 2001 3 
0x7ADE 2002 3 
0x7B40 201 2 
0x7BC0 202 2 

y ahora desea obtener todos los padres de CompanyId 20001, así es como lo hice:

DECLARE @currentLevel smallint 

SELECT @currentLevel = NodeLevel 
FROM Hierarchy 
WHERE CompanyId = 20001; 

with tree([Path], [PathName], CompanyId, [Level]) 
AS 
(
SELECT h.CompanyNode AS [Path], 
     h.CompanyNode.ToString() AS [PathName], 
     h.CompanyId, 
     @currentLevel AS [Level] 
FROM Hierarchy h 
WHERE h.CompanyId = 20001 

UNION ALL 

SELECT h.CompanyNode AS [Path], 
     h.CompanyNode.ToString() AS [PathName], 
     h.CompanyId, 
     CAST((t.[Level] - 1) AS smallint) AS [Level] 
FROM Hierarchy h 
     INNER JOIN tree t ON 
      t.[Path].GetAncestor(1) = h.CompanyNode 
    WHERE h.[NodeLevel] > 0 
) 
SELECT * FROM TREE 
order by [Path] 

puede cambiar la parte recursiva del CTE y no filtrar el nodo superior del árbol.

esperanza que esta ayuda,

Oded

3

Algo como esto avoides el CTE

SELECT t1.NodeId.ToString(), t1.Name 
    FROM (SELECT * FROM test_table2 
     WHERE Name = 'Node 1.1.1') t2 
    , test_table2 t1 
    WHERE 
     t1.NodeId = t2.NodeId OR 
     t2.NodeId.IsDescendantOf(t1.NodeId) = 1 
3

He estado trabajando mucho con HierarchyId últimamente y me encontré con esta pregunta en busca de respuestas a una pregunta diferente Pensé que lanzaría este ejemplo en la mezcla ya que explica algunas cosas. Primero, puede obtener su expresión condicional sin un CTE recursivo. En segundo lugar, GetDescendantOf es inclusivo, por lo que no necesita marcar t1.NodeId = t2.NodeId (y generalmente prefiero las uniones a las subconsultas). He aquí una demostración completa se puede jugar con:

BEGIN TRANSACTION 

CREATE TABLE #HierarchyDemo 
(
    NodeId HIERARCHYID PRIMARY KEY NOT NULL, 
    Description AS NodeId.ToString(), 
    Depth AS NodeId.GetLevel() 
) 

INSERT INTO #HierarchyDemo VALUES (HierarchyId::GetRoot()); 
INSERT INTO #HierarchyDemo VALUES (CAST ('/1979/' AS HIERARCHYID)); 
INSERT INTO #HierarchyDemo VALUES (CAST ('/2012/' AS HIERARCHYID)); 
INSERT INTO #HierarchyDemo VALUES (CAST ('/2012/2/' AS HIERARCHYID)); 
INSERT INTO #HierarchyDemo VALUES (CAST ('/1979/4/' AS HIERARCHYID)); 
INSERT INTO #HierarchyDemo VALUES (CAST ('/2012/2/17/' AS HIERARCHYID)); 
INSERT INTO #HierarchyDemo VALUES (CAST ('/1979/4/6/' AS HIERARCHYID)); 

SELECT * 
FROM #HierarchyDemo; 

SELECT * 
FROM #HierarchyDemo startingPoint 
INNER JOIN #HierarchyDemo parent 
    ON startingPoint.NodeId.IsDescendantOf(parent.NodeId) = 1 
WHERE startingPoint.Description = '/2012/2/17/' 

ROLLBACK TRANSACTION 
0
Declare @hid hierarchyid=0x5D10 -- Child hierarchy id 

SELECT 
* 
FROM 
    dbo.TableName 
WHERE 
    @hid.IsDescendantOf(ParentHierarchyId) = 1  
+1

No cumple la condición fundamental especificada por el OP, obtener todos los padres de un niño. Esto obtiene todos los hijos de un padre. – JamieSee

Cuestiones relacionadas