Using PostgreSQL 9.0.4
Below is a very similar structure of my table:
CREATE TABLE departamento ( id bigserial NOT NULL, master_fk bigint, nome character varying(100) NOT NULL CONSTRAINT departamento_pkey PRIMARY KEY (id), CONSTRAINT departamento_master_fk_fkey FOREIGN KEY (master_fk) REFERENCES departamento (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION ) And the function I created:
CREATE OR REPLACE FUNCTION fn_retornar_dptos_ate_raiz(bigint[]) RETURNS bigint[] AS $BODY$ DECLARE lista_ini_dptos ALIAS FOR $1; dp_row departamento%ROWTYPE; dpto bigint; retorno_dptos bigint[]; BEGIN BEGIN PERFORM id FROM tbl_temp_dptos; EXCEPTION WHEN undefined_table THEN EXECUTE 'CREATE TEMPORARY TABLE tbl_temp_dptos (id bigint NOT NULL) ON COMMIT DELETE ROWS'; END; FOR i IN array_lower(lista_ini_dptos, 1)..array_upper(lista_ini_dptos, 1) LOOP SELECT id, master_fk INTO dp_row FROM departamento WHERE id=lista_ini_dptos[i]; IF dp_row.id IS NOT NULL THEN EXECUTE 'INSERT INTO tbl_temp_dptos VALUES ($1)' USING dp_row.id; WHILE dp_row.master_fk IS NOT NULL LOOP dpto := dp_row.master_fk; SELECT id, master_fk INTO dp_row FROM departamento WHERE id=lista_ini_dptos[i]; EXECUTE 'INSERT INTO tbl_temp_dptos VALUES ($1)' USING dp_row.id; END LOOP; END IF; END LOOP; RETURN ARRAY(SELECT id FROM tbl_temp_dptos); END; $BODY$ LANGUAGE plpgsql VOLATILE Any questions about the names I can translate ..
What is the idea of the function? I first check if the temporary table already exists (perform), and when the exception occurs I create a temporary table.
Then I take each element in the array and use it to fetch the id and master_fk of a department. If the search is successful (check if id is not null, it is even unnecessary) I insert the id in the temporary table and start a new loop.
The second loop is intended to get all parents of that department which was previously found by performing the previous steps (ie, pick a department and insert it into the temporary table).
At the end of the second loop returns to the first. When this one ends I return bigint[] refers to what was recorded in the temporary table.
My problem is that the function returns me the same list I provide. What am I doing wrong?
... WHERE id=dpto. And you should have an infinite loop, unless master_fk is null for the list of ids you supplied.bigintyou want the departments and its parents? Is that so?