【发布时间】:2013-10-15 22:45:38
【问题描述】:
使用 PostgreSQL 9.0.4
下面是我的表格的一个非常相似的结构:
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
)
还有我创建的函数:
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
关于我可以翻译的名字的任何问题..
函数的概念是什么?我首先检查临时表是否已经存在(执行),当异常发生时我创建一个临时表。
然后我获取数组中的每个元素并使用它来获取部门的 id 和 master_fk。如果搜索成功(检查id是否为null,甚至没有必要)我将id插入临时表并开始一个新的循环。
第二个循环旨在获取先前通过执行前面步骤找到的该部门的所有父级(即,选择一个部门并将其插入临时表中)。
在第二个循环结束时返回第一个。当这个结束时,我返回 bigint[] 指的是临时表中记录的内容。
我的问题是该函数返回我提供的相同列表。我做错了什么?
【问题讨论】:
-
第二个循环的选择应该是
... WHERE id=dpto。你应该有一个无限循环,除非你提供的 id 列表的 master_fk 为 null。 -
如果我说得对,你有一个部门“属于”另一个部门,并且给定了一组
bigint,你想要部门和它的父母吗?是这样吗? -
@MatheusOI,结构是基于父母和孩子的关系。一个部门可以是另一个部门的父亲(称为master_fk)。该函数旨在提供与提供的列表中的 ids 相关的所有父母 (bigint [])。
-
@Nicolas,根据我对 MatheusOI 的回答,第二个循环将获取父部门(使用部门子的“master_fk”)并将父亲添加到临时表中。如果 master_fk 为空,则第二个循环停止,因为我找到了根部门。我不知道我的解释是否足够......如果你愿意,我可以制作一个流程图来提供帮助
标签: sql postgresql loops plpgsql common-table-expression