我试图int[][]
在选择查询中的多维数组列()上运行plpgsql函数。
函数是这样的:
CREATE OR REPLACE FUNCTION public.reduce_to_percentages(int[][])
RETURNS float[] AS
$function$
DECLARE
s int[];
a float[];
BEGIN
FOREACH s SLICE 1 IN ARRAY $1 LOOP
a := a || s[2]::float / s[1]::float;
END LOOP;
RETURN a;
END;
$function$
LANGUAGE plpgsql VOLATILE;
以下查询有效:
SELECT reduce_to_percentages(ARRAY[ARRAY[100, 20], ARRAY[300, 50]]);
以下查询也是如此:
SELECT reduce_to_percentages((SELECT counts FROM objects LIMIT 1));
但是以下查询为函数提供了一个null
值,并在尝试FOREACH
覆盖时导致异常$1
:
SELECT reduce_to_percentages(counts) FROM objects;
您可以通过检查诸如@klin提供的NULL
值来修复错误。但这就是在猪身上涂口红。重写该函数以用基于集合的解决方案替换过程循环。通常更快(尤其是在外部查询的上下文中使用时),更简单且自动为null安全:
CREATE OR REPLACE FUNCTION public.reduce_to_percentages(int[])
RETURNS float[] AS
$func$
SELECT ARRAY (SELECT $1[d][2]::float / $1[d][1]
FROM generate_subscripts($1,1) d)
$func$ LANGUAGE sql IMMUTABLE;
有关的:
笔记:
铸造红利来float
就足够了。自动float / integer
返回float
。
没有数据类型int[][]
。只是int[]
。Postgres允许使用这种表示法,但忽略了数组类型的其他数组维,因为所有维的数据类型本身都是相同的。细节:
设置该函数IMMUTABLE
(因为它是)以获得更好的性能并允许建立索引。有关的:
或者,您可以将函数声明为STRICT
(同义词:)RETURNS NULL ON NULL INPUT
。微小的不同:它返回NULL
NULL输入,而不是上面的空数组('{}'
)。
CREATE OR REPLACE FUNCTION public.reduce_to_percentages(int[][])
RETURNS float[] AS
$function$
...
$function$ LANGUAGE plpgsql IMMUTABLE STRICT;
RETURNS NULL ON NULL INPUT
或STRICT
表示该函数总是在其任何参数为null时返回null。如果指定了此参数,则当参数为空时不执行该函数;否则,将不执行该函数。而是自动假定为空结果。
但是,出于多种原因,上面的简单SQL函数是可取的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句