循环功能无法正常工作 [英] Loop in function does not work as expected

查看:62
本文介绍了循环功能无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用PostgreSQL 9.0.4

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
)

我创建的函数:

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.

然后,我将数组中的每个元素都用于获取部门的id和master_fk.如果搜索成功(检查id是否为null,则甚至没有必要),我将id插入临时表并开始新的循环.

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).

第二个循环结束时返回第一个循环.当这结束时,我返回bigint []指向临时表中记录的内容.

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?

推荐答案

有很多 我会做不同的事情,并且效果很好.

There is a lot I would do differently, and to great effect.

从表定义和命名约定开始.这些主要只是意见:

Starting with the table definition and naming conventions. These are mostly just opinions:

CREATE TEMP TABLE conta (conta_id bigint primary key, ...);

CREATE TEMP TABLE departamento (
   dept_id   serial PRIMARY KEY
 , master_id int REFERENCES departamento (dept_id)
 , conta_id  bigint NOT NULL REFERENCES conta (conta_id)
 , nome      text NOT NULL
);

要点

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆