如何创建返回多行的PL/pgSQL函数

Ale*_*ber 4 postgresql stored-procedures return-type plpgsql postgresql-8.4

我正在尝试创建一个PL/pgSQL函数,它应该填充一个临时表,然后从中返回所有行(稍后将是一个连接),但我不知道要为它指定哪种返回类型:

create or replace function pref_daily_misere() returns void as $BODY$
        begin

        create temporary table temp_best (id varchar not null) on commit drop;
        insert into temp_best (id) select id from pref_money where
            yw = to_char(current_timestamp - interval '1 week', 'IYYY-IW')
            order by money desc limit 10;
        select id from temp_best;
        end;
$BODY$ language plpgsql;
Run Code Online (Sandbox Code Playgroud)

上面的陈述单独工作,但给我错误

# select pref_daily_misere();
ERROR:  query has no destination for result data
HINT:  If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT:  PL/pgSQL function "pref_daily_misere" line 7 at SQL statement
Run Code Online (Sandbox Code Playgroud)

当我尝试在我的PostgreSQL 8.4.11数据库中调用它时.

这可能是因为我错误地指定了空返回之上,但我不知道哪个返回类型改为使用,并省略返回类型是一个编译错误.

mu *_*ort 5

您想使用setof varchar返回类型然后return query ...在函数内部.从精细手册:

39.6.1.2.返回下一步并返回查询

RETURN NEXT expression;
RETURN QUERY query;
RETURN QUERY EXECUTE command-string [ USING expression [, ... ] ];
Run Code Online (Sandbox Code Playgroud)

当声明PL/pgSQL函数返回SETOF sometype时,要遵循的过程略有不同.在这种情况下,要返回的各个项由一系列RETURN NEXT或多个RETURN QUERY命令指定,然后RETURN使用不带参数的最终命令来指示该函数已完成执行.

我想你想要更像这样的东西:

create or replace function pref_daily_misere() returns setof varchar as $BODY$
begin
    create temporary table temp_best (id varchar not null) on commit drop;
    insert into temp_best (id)
    select id
    from pref_money
    where yw = to_char(current_timestamp - interval '1 week', 'IYYY-IW')
    order by money
    desc limit 10;
    return query select id from temp_best;
    return;
end;
$BODY$ language plpgsql;
Run Code Online (Sandbox Code Playgroud)

但是,临时表在这里毫无意义:

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

所以PostgreSQL正在计算整个结果集并自行缓存它.你可以这样做:

create or replace function pref_daily_misere() returns setof varchar as $BODY$
begin
    return query
        select id
        from pref_money
        where yw = to_char(current_timestamp - interval '1 week', 'IYYY-IW')
        order by money
        desc limit 10;
    return;
end;
$BODY$ language plpgsql;
Run Code Online (Sandbox Code Playgroud)

我很确定无论如何都会在你的函数结束时删除临时表,所以你应该摆脱它.

  • @AlexanderFarber:第二个`return;`是没有必要的,但是文档说"没有参数的最终`RETURN`命令用于表示函数已经完成执行"所以我把它放进去以避免对它为什么不存在的问题在那里:) (2认同)