在同一Postgres函数中使用return next和return查询

时间:2014-04-23 15:49:19

标签: database function postgresql plpgsql

我是PostgreSQL的新手(使用v9.0),想知道在结果集中附加结果之前是否可以在同一函数中使用return nextReturn query而不退出函数?

CREATE TYPE return_type AS
   (paramname character varying,
    value character varying);

CREATE OR REPLACE FUNCTION myfuntion(param1 character varying)
RETURNS SETOF return_type AS
declare
r return_type;
message varchar;
status integer;
$BODY$
BEGIN
o_call_status := 0;
o_call_message := '';
        Return query Select 'mystatus' as paramName, status::varchar as value;
        Return query Select 'mymessage' as paramName, message as value;

       for r in SELECT 'mycolumnname1' as paramName,mycolumn1 as value FROM tb1 
                WHERE column1 = val
                UNION ALL
                SELECT 'mycolumnname2' as paramName,mycolumn2 as value  FROM tb1 
                WHERE column1 = val
                UNION ALL
                SELECT 'mycolumnname3' as paramName,mycolumn3 as value  FROM tb2 
                WHERE column1 = val1 AND
                column4 = val4  loop
          return next r;
        end loop;

        END;
        $BODY$
LANGUAGE plpgsql VOLATILE

2 个答案:

答案 0 :(得分:1)

从plpgsql函数返回

您可以自由反复地混合RETURN NEXTRETURN QUERY。基本原则是plpgsql在本地构建表,并且在函数完成之前不会返回:

Per documentation:

  

注意:RETURN NEXTRETURN QUERY的当前实施   如上所述,在从函数返回之前存储整个结果集。

这意味着如果你对目前的结果不满意并且客户不会看到任何东西,你甚至可以提出异常中止操作。我们还在手册中包含了一个示例,正好在上述引用之上。

交叉制表

至于您尝试实现的目标,请考虑tablefunc扩展名的crosstab()函数。相关答案详尽的细节:
PostgreSQL Crosstab Query

答案 1 :(得分:0)

我不确定你是否可以将两者混合(试试......)。

也就是说,在用例中使用union all all子句直接返回所有行时,它会更有效率:

return query
select 'mystatus' as paramName, status::varchar as value
union all
select 'mymessage' as paramName, message as value
union all
SELECT 'mycolumnname1' as paramName,mycolumn1 as value
FROM tb1
WHERE column1 = val
union all
…

您可能还会发现此contrib模块很有用,顺便说一下:

http://www.postgresql.org/docs/current/static/tablefunc.html

并且,如果可能的话,重新访问您的架构或使用它的方式,因此您不需要这种函数开始 - 设置返回潜在大型集合的函数可能效率特别低。在您的情况下,您似乎想要三列。为什么不简单使用?

select col1, col2, col3 from tbl