使用数组中的每个元素调用集合返回函数
Posted
技术标签:
【中文标题】使用数组中的每个元素调用集合返回函数【英文标题】:Calling set-returning function with each element in array 【发布时间】:2013-02-06 16:06:51 【问题描述】:我有一个集合返回函数 (SRF),它接受一个整数参数并从表中返回一组行。我使用SELECT * FROM tst.mySRF(3);
调用它,然后像处理表格一样操作返回的值。
我想做的是在数组的每个元素上执行它;但是,当我使用SELECT * FROM tst.mySRF(unnest(array[3,4]));
调用它时,会返回错误“在不能接受集合的上下文中调用的集合值函数”。如果我改为使用SELECT tst.mySRF(unnest(array[3,4]));
调用它,我会得到一组tst.tbl
类型。
表定义:
DROP TABLE tst.tbl CASCADE;
CREATE TABLE tst.tbl (
id serial NOT NULL,
txt text NOT NULL,
PRIMARY KEY (id)
);
INSERT INTO tst.tbl(txt) VALUES ('a'), ('b'), ('c'), ('d');
函数定义:
CREATE OR REPLACE FUNCTION tst.mySRF(
IN p_id integer
)
RETURNS setof tst.tbl
LANGUAGE plpgsql
AS $body$
DECLARE
BEGIN
RETURN QUERY
SELECT id, txt
FROM tst.tbl
WHERE id = p_id;
END;
$body$;
来电:
SELECT * FROM tst.mySRF(3)
按预期返回一个表。
正如预期的那样,SELECT tst.mySRF(unnest(array[3,4]))
返回一个包含 tst.tbl
类型的单列的表。
SELECT * FROM tst.mySRF(unnest(array[3,4]))
返回上面描述的错误,我期待一个表。
【问题讨论】:
是的。你写的是正确的。你的问题是什么?您不能在内部函数返回记录集的地方运行 select * from function(function())。 问题是如何在不使用一系列 UNION 语句的情况下,为数组的每个元素执行一个函数并获得一个表。 好吧,你展示了它 - 选择函数(other_function())。如果您出于某种原因不能这样做,在 9.3 上您可以使用 LATERAL,在以前的版本中 - 使用我在此处描述的工作方法:depesz.com/2012/08/19/… @depesz 但是 select function(other_function()) 返回的表是 tst.tbl 行的单列表。如何将其转换为 tst.tbl 类型的多列表?还是需要您提到的 9.3 功能? 【参考方案1】:为避免“单列表”问题,您需要使用(row).*
符号显式扩展 SRF 结果
SELECT (tst.mySRF(unnest(array[3,4]))).*;
如果我理解@depesz,LATERAL
将提供一种更有效或更直接的方式来实现相同的结果。
【讨论】:
以上是关于使用数组中的每个元素调用集合返回函数的主要内容,如果未能解决你的问题,请参考以下文章