Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   MS SQL Server (https://www.clubdelphi.com/foros/forumdisplay.php?f=23)
-   -   Tabla cíclica ó estructura de arbol... (https://www.clubdelphi.com/foros/showthread.php?t=59740)

Xianto 06-09-2008 01:36:36

Tabla cíclica ó estructura de arbol...
 
Buenas... necesito crear una tabla que tiene 1 padre, hijos, nietos, etc... asi de forma recursiva... pueden ser 5 o 20 ramificaciones.

Estas tablas son conocidas como cíclicas y tenia algo de ello en algun manual... pero no tengo idea donde esta el manual, jejejejeje.

Alguien me haría el favor de recordarme como era la teoría del tema, que estoy un poco oxidado con ello ???

Gracias!

duilioisola 07-09-2008 21:21:57

Pues puedes crear una tabla que tenga:

id, id_hijo, datos_varios.

Cada elemento estará identificado por id.
Si buscas los hijos de id, buscarás los id_hijo de un cierto id.
Si buscas el padre, buscarás el id, cuyo id_hijo es este elemento.
Si buscas el nieto, buscarás los elementos cuyo id sea el id_hijo .

Si existe la posibilidad de recursividad, deberás poner algún control, para que una búsqueda no sea infinita.

Neftali [Germán.Estévez] 08-09-2008 09:33:02

Puedes buscar apuntes sobre el modelo Entidad-Relación (debe haber a montones) y leer sobre las relaciones Reflexivas.

jcarteagaf 11-09-2008 11:37:18

Tengo una tabla con la siguiente estructura:

Código SQL [-]
CREATE TABLE Arbol (
IDOPCION INT NOT NULL,
IDPADRE INT NOT NULL DEFAULT 0,
DESCRIPCION VARCHAR(50),
CONSTRAINT ArbolKey PRIMARY KEY (IDOPCION))

En esa tabla guardo la información de la estructura ciclica.

El siguiente procedimiento me devuelve la información de la tabla
Código SQL [-]
CREATE PROCEDURE Arbol_ABM_Opciones
-- =============================================
-- Author:        Juan Carlos Arteaga
-- Create date: 17/08/2008
-- Description:    Genera el Arbol de Opciones para el ABM
-- =============================================
AS
BEGIN
    SET NOCOUNT ON;

    CREATE TABLE #work (lvl int, IdOpcion int) 
    CREATE TABLE #Opciones (seq int identity, lvl int, IdOpcion int) 
 
    DECLARE @lvl int, @curr int 
    SET @lvl=1
    INSERT INTO #work (lvl, IdOpcion)
    SELECT 1,IDOPCION
    FROM Arbol
    WHERE IdPadre=0
    
    WHILE (@lvl > 0)
    BEGIN 
        IF EXISTS(SELECT * FROM #work WHERE lvl=@lvl)
        BEGIN 
            SELECT TOP 1 @curr=IdOpcion FROM #work 
            WHERE lvl=@lvl 
 
            INSERT #Opciones (lvl, IdOpcion) VALUES (@lvl, @curr) 
 
            DELETE #work 
            WHERE lvl=@lvl and IdOpcion=@curr 
 
            INSERT #work 
            SELECT @lvl+1, IdOpcion 
            FROM Arbol 
            WHERE IdPadre=@curr 
                AND IdPadre <> IdOpcion 
 
            IF (@@ROWCOUNT > 0)
                SET @lvl=@lvl+1 
        END
        ELSE 
            SET @lvl=@lvl-1 
    END 
 
    SELECT d.seq,d.IdOpcion,i.Descripcion,i.IdPadre
    FROM #Opciones d
    JOIN Arbol i ON (d.IdOpcion=i.IdOpcion) 
    ORDER BY seq 

    DROP TABLE #Work
    DROP Table #Opciones
END

Todos los nodos raiz (puedo tener mas de uno) tienen como padre el valor 0.

Ya en Delphi cargo esta estructura en un TTreeView (tvDatos) usando el siguiente procedimiento (spArbolABM es el TADOStoredProc que llama al anterior Procedimiento Almacenado):

Código Delphi [-]
Type
   // Para almacenar datos que quiero asociar a cada nodo
   PItem = ^TItem;
  TItem = record
    IdOpcion : integer;
  end;

...

var
  tnNodoActual : TTreeNode;  // Siempre apunta al nodo seleccionado

...

procedure TfrmABMMenu.Cargar_Arbol;
var
  TPrimerNodo: TTreeNode;
  i: integer;
  MyItem : PItem;

  procedure Rama(iCodigo: Integer; NodoPadre: TTreeNode);
  // Procedure recursivo que carga una rama
  var
    iCodPadre: integer;
    TNodoPadre: TTreeNode;
  begin
    if (spArbolABMIDPADRE.Value = iCodigo) then
      while (spArbolABMIDPADRE.Value = iCodigo) and (not spArbolABM.EOF) do
      begin
        inc(i);
        new(MyItem);
        MyItem.IdOpcion := spArbolABMIDOPCION.AsInteger;
        TNodoPadre := tvDatos.Items.AddChildObject(NodoPadre,
          spArbolABMDESCRIPCION.AsString,MyItem);
        iCodPadre := spArbolABMIDOPCION.Value;
        spArbolABM.Next;
        Application.ProcessMessages;
        Rama(iCodPadre, TNodoPadre);
      end;
  end;
begin
  i := 0;
  tvDatos.Items.Clear;
  spArbolABM.close;
  spArbolABM.Open;
  Screen.Cursor := crHourGlass;
  try
    if not spArbolABM.IsEmpty then
      Rama(0, nil);
  finally
    Screen.Cursor := crDefault;
    tvDatos.Selected := tvDatos.Items.GetFirstNode;
    tnNodoActual := tvDatos.Selected;
  end;
  spArbolABM.close;
end;

Espero que sea de utilidad.

Saludos


La franja horaria es GMT +2. Ahora son las 01:17:52.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi