还有 很多 我会做出不同的,并且很大的影响。
表定义从表定义和命名约定开始。这些主要只是意见:
要点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);
您确定需要
bigserial
部门吗?在这个星球上几乎没有那么多。一个平原serial
就足够了。我很少使用
character varying
长度限制。与其他一些RDBMS不同,使用限制不会带来任何性能提升。CHECK
如果您确实需要实施最大长度,请添加一个约束。我只是使用text
,主要是为了省掉麻烦。我建议使用一种命名约定,其中外键列与引用的列共享名称,因此
master_id
代替master_fk
,等等。还允许USING
在联接中使用。而且我 很少 使用非描述性的列名
id
。dept_id
在这里使用代替。
它可以在很大程度上简化为:
CREATE OR REPLACe FUNCTION f_retornar_plpgsql(lista_ini_depts VARIADIC int[]) RETURNS int[] AS$func$DECLARE _row departamento; -- %ROWTYPE is just noiseBEGINIF NOT EXISTS ( -- simpler in 9.1+, see below SELECT FROM pg_catalog.pg_class WHERe relnamespace = pg_my_temp_schema() AND relname = 'tbl_temp_dptos') THEN CREATE TEMP TABLE tbl_temp_dptos (dept_id bigint NOT NULL) ON COMMIT DELETe ROWS;END IF;FOR i IN array_lower(lista_ini_depts, 1) -- simpler in 9.1+, see below .. array_upper(lista_ini_depts, 1) LOOP SELECT * INTO _row -- since rowtype is defined, * is best FROM departamento WHERe dept_id = lista_ini_depts[i]; ConTINUE WHEN NOT FOUND; INSERT INTO tbl_temp_dptos VALUES (_row.dept_id); LOOP SELECt * INTO _row FROM departamento WHERe dept_id = _row.master_id; EXIT WHEN NOT FOUND; INSERT INTO tbl_temp_dptos SELECt _row.dept_id WHERe NOT EXISTS ( SELECT FROM tbl_temp_dptos WHERe dept_id =_row.dept_id); END LOOP;END LOOP;RETURN ARRAY(SELECt dept_id FROM tbl_temp_dptos);END$func$ LANGUAGE plpgsql;
称呼:
SELECt f_retornar_plpgsql(2, 5);
或者:
SELECT f_retornar_plpgsql(VARIADIC '{2,5}');
ALIAS FOR
是过时的语法,不鼓励使用。请改用功能参数。该
VARIADIC
参数使调用更加方便。有关的:- 在单个参数中传递多个值
- 您不需要
EXECUTE
没有动态元素的查询。在这里没有收获。
您不需要异常处理即可创建表。在这里引用手册:
提示:与没有
EXCEPTION子句的块相比,包含子句的块的进入和退出成本要高得多。因此,请不要使用EXCEPTION而无需使用。
- Postgres 9.1或更高版本具有
CREATE TEMP TABLE IF NOT EXISTS
。我使用9.0的解决方法来有条件地创建临时表。
话虽如此,这真是 令人 the舌: 您不需要大部分。
带rCTE的SQL函数即使在Postgres 9.0中,
递归CTE也
使这一过程变得更加 简单 :
CREATE OR REPLACE FUNCTION f_retornar_sql(lista_ini_depts VARIADIC int[]) RETURNS int[] AS$func$WITH RECURSIVE cte AS ( SELECT dept_id, master_id FROM unnest() AS t(dept_id) JOIN departamento USING (dept_id) UNIOn ALL SELECt d.dept_id, d.master_id FROM cte JOIN departamento d ON d.dept_id = cte.master_id )SELECt ARRAY(SELECT DISTINCT dept_id FROM cte) -- distinct values$func$ LANGUAGE sql;
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)