在自定义函数中使用SQL查询作为数组参数(输入)

时间:2016-12-29 16:28:58

标签: sql arrays postgresql plpgsql

我在pl / pgsql中创建了一个自定义函数,它的唯一输入是一个数组。我想使用查询的结果作为此自定义函数的输入,但似乎无法正确。我将使用一个更简单的函数作为示例,并且比我尝试用作输入的查询更简单。

功能定义:

CREATE OR REPLACE FUNCTION bigger_than_ones(input_array int[])
returns SETOF int
AS
$$
DECLARE
  array_item int;
BEGIN
  FOREACH array_item in ARRAY input_array
  LOOP
    IF array_item > 1 THEN
      RETURN NEXT array_item;
    END IF;
  END LOOP;
END
$$ LANGUAGE plpgsql;

我有一个表,其列的数组类型与数组数据类型相同。在这种情况下,整数列:

SELECT * FROM my_table;
id | int_attribute
---+--------------
1  | 2
2  | 3
3  | 1
4  | 4
5  | 1
6  | 6
7  | 1
8  | 1
9  | 8

我想使用一个返回该数据类型列的查询作为我的函数的输入。我尝试了一些这方面的变化,没有任何运气:

SELECT * FROM bigger_than_ones(SELECT int_attribute FROM my_table);

要返回:

result 
-------------
2
3
4
6
8

我使用类似结构化函数的原因是因为我需要在我的代码中的多个位置从多个表计算得到的合并时间范围(自定义类型)。我最好的想法是创建一个能够做到这一点的函数,使用所有时间范围作为输入,无论我从哪里开始,所以我不必每次都进行更复杂的查询。

对我缺少什么的想法?

3 个答案:

答案 0 :(得分:1)

您找到的是ARRAY constructor,它不是运算符(也不是函数),而是SQL构造(SQL语法元素)。引用的答案使用了错误的术语(现已修复)。差异可能很重要。

SELECT * FROM bigger_than_ones(ARRAY(SELECT int_attribute FROM my_table));

你也可以使用基本的aggregate function array_agg(),它更容易集成到更复杂的查询中 - 但对于简单的情况则更慢:

SELECT * FROM bigger_than_ones((SELECT array_agg(int_attribute) FROM my_table));

相关:

我假设你知道unnest()?它可用于从根本上简化您的测试功能:

CREATE OR REPLACE FUNCTION bigger_than_ones(input_array int[])
  RETURNS SETOF int AS
$func$
   SELECT *
   FROM   unnest(input_array) elem
   WHERE  elem > 1;
$func$  LANGUAGE sql;

此外,对于所有这些,通常采用基于集合的方法。从集合构造一个数组只是为了将它传递给函数可能是不必要的复杂化。

答案 1 :(得分:0)

我终于在另一个SO问题中找到了解决方案:Store select query's output in one array in postgres

我能够使用array()运算符,如下所示:

SELECT * FROM bigger_than_ones(ARRAY(SELECT int_attribute FROM my_table));

获得了预期的输出。

答案 2 :(得分:-2)

您是否尝试过创建自定义类型?有一些集合类型,如数组和表,并且有类似于单行记录的对象类型。然后,您可以创建此自定义类型的变量以用作参数。

以下是一个例子:

  

CREATE或REPLACE TYPE namearray AS VARRAY(3)OF VARCHAR2(10);