sábado, 10 de enero de 2009

Listar los padres de una hoja en un arbol


En un tabla arbol, si tengo el identificador de una hoja(9) y quiero listar los padres de esta(5,2,1) hasta llegar a la raiz del arbol, puedo utilizar la funcion que muestro a continuacion, esta funcion es util para realizar consolidaciones(sumas de datos de hojas a los padres).

si tenemos la siguiente tabla:

POSTGRES SQL
create table tabla(
 id_campo serial primary key,
 id_campo_padre integer references tabla (id_campo),
 hoja boolean default true,
 codigo_campo text,
 campo text,
 nivel integer
);


create or replace function reporte_padres(_tabla text, _id_campo text
, _id_padre text, _codigo text, _campo text, _id integer)
returns setof record as $$
----------------------------
-- Autor: Luis A. Jordan P.
----------------------------
declare
 _sql text;
 _bucle record;
 _bucle1 record;
 _bucle2 record;
begin
 _sql := '
 SELECT ' || _id_campo || '::integer as id_campo
 , ' || _id_padre || '::integer as id_padre, ' ||
 _codigo || '::text as codigo, ' || _campo || '::text as campo
 , nivel::integer FROM ' || _tabla || ' WHERE ' || _id_campo || ' = ' || _id ;
 if _sql is null then
  raise exception 'Se coloco un nulo al formar el arbol de padres:
   SELECT %::integer as id_campo, %::integer as id_padre, %::text as codigo
   , %::text as campo, nivel::integer FROM % WHERE % = %
  ',_id_campo,_id_padre,_codigo,_campo,_tabla,_id_campo,_id;
 end if;
 for _bucle in
  execute _sql
 loop
  if(_bucle.id_padre<>_bucle.id_campo) then
   for _bucle1 in
    SELECT * FROM reporte_padres(_tabla, _id_campo
    , _id_padre, _codigo, _campo, _bucle.id_padre)
    as (id_campo integer, id_padre integer, codigo text
    , campo text, nivel integer) ORDER BY codigo
   loop 
    return next _bucle1;
   end loop;
  end if;
  return next _bucle;
 end loop;
 return ;
end;
$$ language plpgsql;



SELECT * FROM reporte_padres('tabla','id_campo', 'id_campo_padre'
, 'codigo', 'campo', 10)
AS (id_campo integer, id_padre integer, codigo text, campo text, nivel integer);

No hay comentarios: