10

是否可以将 postgres 查询的结果作为输入传递给另一个函数?

作为一个非常人为的例子,假设我有一个查询,例如

SELECT id, name
FROM users
LIMIT 50

我想创建一个函数my_function,它接受第一个查询的结果集并返回最小 id。这在 pl/pgsql 中可能吗?

SELECT my_function(SELECT id, name FROM Users LIMIT 50); --returns 50
4

4 回答 4

4

您可以使用cursor,但这对于计算最小值非常不切实际。

我会为此目的使用一个临时表,并传递表名以在动态 SQL中使用:

CREATE OR REPLACE FUNCTION f_min_id(_tbl regclass, OUT min_id int) AS 
$func$
BEGIN

EXECUTE 'SELECT min(id) FROM ' || _tbl
INTO min_id;

END  
$func$ LANGUAGE plpgsql;

称呼:

CREATE TEMP TABLE foo ON COMMIT DROP AS
SELECT id, name
FROM   users
LIMIT  50;

SELECT f_min_id('foo');

要点

-> SQLfiddle 演示

于 2013-10-16T01:52:28.713 回答
4

我会在另一边解决问题,为结果集的每条记录调用一个聚合函数。它没有那么灵活,但可以为您提供工作提示。

作为遵循您的示例问题的示例:

CREATE OR REPLACE FUNCTION myMin ( int,int ) RETURNS int AS $$
  SELECT CASE WHEN $1 < $2 THEN $1 ELSE $2 END;
$$ LANGUAGE SQL STRICT IMMUTABLE;

CREATE AGGREGATE my_function ( int ) (
    SFUNC = myMin, STYPE = int, INITCOND = 2147483647 --maxint
);

SELECT my_function(id) from (SELECT * FROM Users LIMIT 50) x; 
于 2013-10-30T22:14:19.760 回答
3

不可能将泛型类型 RECORD 的数组传递给 plpgsql 函数,这本质上是您正在尝试做的事情。

您可以做的是传入特定用户定义类型或特定表行类型的数组。在下面的示例中,您还可以将参数数据类型换成表名 users[](尽管这显然意味着获取 users 表行中的所有数据)。

CREATE TYPE trivial {
"ID" integer,
"NAME" text
}

CREATE OR REPLACE FUNCTION trivial_func(data trivial[])
  RETURNS integer AS
$BODY$
DECLARE 

BEGIN
    --Implementation here using data
    return 1;

END$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
于 2013-10-11T06:18:19.137 回答
1

我认为没有办法将记录集或表格传递给函数(但如果我错了,我会很高兴)。我可以建议的最好的方法是传递数组:

create or replace function my_function(data int[])
returns int
as
$$
   select min(x) from unnest(data) as x
$$
language SQL;

sql 小提琴演示

于 2013-08-14T04:41:25.180 回答