簡體   English   中英

具有整數數組的PL / pgSQL函數語法

[英]PL/pgSQL function syntax with integer arrays

我正在嘗試啟動SQL函數,以便可以收集我不想在其他查詢中使用的部件ID的列表。 我嘗試使用PGAdmin的“函數”構建器開始使用,但是我遇到語法錯誤,因此它不會創建該函數。 有人可以告訴我我在做什么錯嗎? 一旦我可以啟動該功能,我想我可以找出其余的功能。 只需找出正確的聲明語法(我更習慣於MSSQL的Transaction 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的整數數組。

具有正確語法的示例函數:

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函數具有局部變量。

@klin的回復是正確的,我有一個建議。 請改用SQL語言。 在這種情況下,PostgreSQL計划者可以使用更好的計划。 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函數通常更好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM