是否可以将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
答案 0 :(得分:2)
无法将通用类型RECORD的数组传递给plpgsql函数,而这正是您尝试执行的操作。
您可以做的是传入特定用户定义的TYPE或特定表行类型的数组。在下面的示例中,您还可以替换表名称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;
答案 1 :(得分:2)
我会在另一方面解决问题,为结果集的每条记录调用aggregate function。它不是那么灵活,但可以提供一些工作提示。
作为示例来解决您的示例问题:
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;
答案 2 :(得分:1)
您可以使用光标,但这对于计算最小值非常不切实际。
为此,我会使用临时表,并传递表名,以便在动态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');
第一个参数是regclass
类型,以防止SQL注入。 More info in this related answer on dba.SE
我制作了临时表ON COMMIT DROP
以将其生命周期限制为当前事务。可能是也可能不是你想要的。
您可以扩展此示例以获取更多参数。 Search for code examples for dynamic SQL with EXECUTE
答案 3 :(得分:0)
我认为没有办法将记录集或表传递给函数(但如果我错了,我会很高兴)。我建议的最好是传递数组:
create or replace function my_function(data int[])
returns int
as
$$
select min(x) from unnest(data) as x
$$
language SQL;