带整数数组的PL / pgSQL函数语法

时间:2015-10-21 22:28:55

标签: sql arrays postgresql function plpgsql

我试图启动一个SQL函数,以便我可以在另一个查询中收集我不想要的部分ID列表。我已尝试使用PGAdmin的“函数”构建器开始,但我遇到语法错误,因此无法创建该函数。谁能告诉我这里做错了什么?一旦我能够启动该功能,我想我可以弄清楚剩下的。只需要弄清楚正确的声明语法(我更常用于MSSQL的事务SQL语法)

到目前为止,这是我的代码:

CREATE FUNCTION get_unused_part_ids() RETURNS integer[] AS
$BODY$DECLARE
  part_ids integer ARRAY;

BEGIN
  set part_ids = '{1,2,3,4}'
  select part_ids

END;$BODY$
LANGUAGE sql VOLATILE;

我期待的是一个整数数组,其值为1,2,3和4.

2 个答案:

答案 0 :(得分:1)

具有正确语法的示例函数:

CREATE FUNCTION get_unused_part_ids() RETURNS integer[] AS
$BODY$
DECLARE
    part_ids integer ARRAY;

BEGIN
    part_ids = '{1,2,3,4}';
    return part_ids;
END;
$BODY$ LANGUAGE plpgsql;

select * from get_unused_part_ids();

 get_unused_part_ids 
---------------------
 {1,2,3,4}
(1 row) 

注意,您需要plpgsql函数来获取局部变量。

答案 1 :(得分:0)

@klin的回复是正确的,我有一个建议。请改用SQL语言。在描述的情况下,PostgreSQL planner可以使用更好的计划。 PLpgSQL函数是规划器的黑盒子:

CREATE OR REPLACE FUNCTION public.foo1()
 RETURNS integer[]
 LANGUAGE plpgsql
AS $function$
BEGIN
  RETURN ARRAY[1,2,3,4];
END;
$function$

CREATE OR REPLACE FUNCTION public.foo2()
 RETURNS integer[]
 LANGUAGE sql
AS $function$
  SELECT ARRAY[1,2,3,4];
$function$

CREATE TABLE boo(a int);
INSERT INTO boo SELECT random()*10 FROM generate_series(1,10000);
ANALYZE boo;
postgres=# EXPLAIN ANALYZE SELECT * FROM boo WHERE a = ANY(foo1());
                                             QUERY PLAN                                               
═════════════════════════════════════════════════════════════════════════════════════════════════════
Seq Scan on boo  (cost=0.00..2770.00 rows=6145 width=4) (actual time=0.118..49.949 rows=4104 loops=1)
  Filter: (a = ANY (foo1()))
  Rows Removed by Filter: 5896
Planning time: 0.096 ms
Execution time: 50.900 ms
(5 rows)

Time: 51.771 ms
postgres=# EXPLAIN ANALYZE SELECT * FROM boo WHERE a = ANY(foo2());
                                            QUERY PLAN                                              
═══════════════════════════════════════════════════════════════════════════════════════════════════
Seq Scan on boo  (cost=0.00..195.00 rows=4104 width=4) (actual time=0.036..4.700 rows=4104 loops=1)
  Filter: (a = ANY ('{1,2,3,4}'::integer[]))
  Rows Removed by Filter: 5896
Planning time: 0.193 ms
Execution time: 5.254 ms
(5 rows)

使用SQL函数可以获得更好的结果估计。 SQL函数是一个宏 - 如果你使用SQL函数,那么它等同于直接编写的查询:

postgres=# EXPLAIN ANALYZE SELECT * FROM boo WHERE a = ANY(ARRAY[1,2,3,4]);
                                                QUERY PLAN                                              
═══════════════════════════════════════════════════════════════════════════════════════════════════
Seq Scan on boo  (cost=0.00..195.00 rows=4104 width=4) (actual time=0.032..4.782 rows=4104 loops=1)
  Filter: (a = ANY ('{1,2,3,4}'::integer[]))
  Rows Removed by Filter: 5896
Planning time: 0.122 ms
Execution time: 5.325 ms
(5 rows)

在这种情况下,优化器具有更多信息并且可以使用它。对于具有常量结果的函数,SQL函数通常更好。