我使用 Postgresql 9.1 和 ubuntu 12.04。
受 Craig 对我的问题Concatenation of setof type or setof record的启发,我想我可以很好地使用return query
,setof record
和一个系列生成器到这个 plpgsql 函数中:
create or replace function compute_all_pair_by_craig(id_obj bigint)
returns setof record as $$
begin
return query select o.id, generate_series(0,o.value) from m_obj as o;
end;
$$ language plpgsql;
在执行期间,我收到错误:
ERROR: set_valued function called in context that cannot accept a set
怎么了 ?与克雷格相反,我告诉函数 return setof record
。
我可以实现与 Craig 完全一样的工作,即通过定义一个类型create type pair_id_value as (idx bigint, value integer)
并让我的 plpgsql 函数返回 asetof of pair_id_value
而不是 a setof record
。
但是即使使用这个可行的解决方案,我仍然不明白为什么select id, generate_series(0,13)
单独会在两列中返回结果......相反,调用函数(返回 setof pair_id_value)只会在字段看起来像的一列return query select id, generate_series(0,my_obj.value) from my_obj
中返回结果这个“(123123,0)”“(123123,1)”“(123123,2)”(3行)显然是元组。
是否必须/应该创建临时表?
错误消息不是很有帮助:
但是,如果您改写查询以将其称为正确的集合返回函数,您将看到真正的问题:
如果您在
SETOF RECORD
没有OUT
参数列表的情况下使用,则必须在调用语句中指定结果,例如:RETURNS TABLE
但是,使用或OUT
参数要好得多。使用前一种语法,您的函数将是:这可以在 SELECT-list 上下文中调用,并且可以在不显式创建类型或在调用站点指定结果结构的情况下使用。
至于问题的后半部分,发生的情况是第一种情况在 SELECT 列表中指定了两个单独的列,而第二种情况返回单个组合。这实际上与您如何返回结果无关,而是您如何调用该函数。如果我们创建示例函数:
您将看到调用 set-returning 函数的两种方式的区别 - 在
SELECT
列表中,一个具有古怪行为的 PostgreSQL 特定非标准扩展:或以更标准的方式作为表格: