从“选择语句”格式的函数返回结果

Posted

技术标签:

【中文标题】从“选择语句”格式的函数返回结果【英文标题】:Returning results from a function in 'select statement' format 【发布时间】:2013-05-21 18:04:25 【问题描述】:

我有一个看起来像这样的函数:

CREATE OR REPLACE FUNCTION mffcu.test_ty_hey()
 RETURNS setof record
 LANGUAGE plpgsql
AS $function$
Declare
       cname1 text;   
       sql2 text;      
Begin 
for cname1 in 
select array_to_string(useme, ', ') from (
select array_agg(column_name) as useme
from(
select column_name::text
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'crosstab_183' 
and ordinal_position != 1
) as fin
) as fine
loop  
sql2 := 'select distinct array['|| cname1 ||'] from mffcu.crosstab_183';
execute sql2;
end loop;
END;
$function$

我用这个来调用函数:

select mffcu.test_ty_hey()

如何在不创建表/临时表的情况下返回sql2 查询的结果?

【问题讨论】:

您忘记提及您的 PostgreSQL 版本。 @ErwinBrandstetter 它是 psql 9.1 版,服务器 9.0 版。 【参考方案1】:

当然,虽然@Pavel 是对的,但您非常复杂的函数可以解开为:

CREATE OR REPLACE FUNCTION mffcu.test_ty_hey()
  RETURNS SETOF text[] LANGUAGE plpgsql
AS $func$
DECLARE
    cname1 text;   
BEGIN 

FOR cname1 IN 
    SELECT column_name::text
    FROM   information_schema.columns
    WHERE  table_name = 'crosstab_183' 
    AND    table_schema = 'mffcu' 
    AND    ordinal_position <> 1
LOOP
    RETURN QUERY
    EXECUTE format('SELECT DISTINCT ARRAY[%I::text]
                    FROM   mffcu.crosstab_183', cname1);
END LOOP;

END
$func$

format() 需要 PostgreSQL 9.1 或更高版本。在 9.0 中,您可以替换为:

EXECUTE 'SELECT DISTINCT ARRAY['|| quote_ident(cname1) ||'::text]
         FROM   mffcu.crosstab_183';

呼叫:

select <b>* FROM</b> mffcu.test_ty_hey();

通过将每一列转换为text,我们得到了一个一致的数据类型,可以用来声明RETURN 类型。必须做出这种折衷以从一个函数返回各种数据类型。每种数据类型都可以转换为text,这是显而易见的共同点。

顺便说一句,我很难想象每个值的 ARRAY 包装器应该有什么用处。我想你可以放弃它。

【讨论】:

这段代码什么都不做,你必须使用 RETURN QUERY EXECUTE。只有 EXECUTE 的结果不会转发到输出。 @PavelStehule:谢谢。添加了缺少的RETURN QUERY 添加 RETURN QUERY 时出现此错误:RETURN cannot have a parameter in function return set;在“QUERY”处或附近使用 RETURN NEXT @precose:它现在应该可以工作了,我修复了两个疏忽并进行了测试。【参考方案2】:

PostgreSQL 函数在执行前应该有固定的结果类型。您不能在执行后期指定类型。只有两种解决方法 - 使用临时表或使用游标。

PLpgSQL 语言不适合过于通用的例程 - 它有利于实现严格和干净的业务规则。对通用交叉表计算或通用审计或类似的通用任务不利。它可以工作,但代码速度较慢并且通常无法很好地维护。

但是回复您的查询,您可以使用输出游标

示例http://okbob.blogspot.cz/2008/08/using-cursors-for-generating-cross.html

【讨论】:

以上是关于从“选择语句”格式的函数返回结果的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQl 函数返回多个动态结果集

Laravel DB 选择语句。查询返回列名作为结果而不是值

在 select 语句中使用函数结果

遍历选择结果

以 XML/JSON 格式返回 Google Analytics Reporting API 结果

为啥使用 Pandas 的 max 和 min 函数会返回意外结果?