首页 > 解决方案 > Postgres函数将表返回到变量中

问题描述

我怎样才能将不同的列捕获到不同的变量中(注意这只是伪代码,所以我假设它会导致错误。示例取自这里

create or replace function get_film (
  p_pattern varchar
) 
    returns table (
        film_title varchar,
        film_release_year int
    ) 
    language plpgsql
as $$
begin
    return query 
        select
            title,
            release_year::integer
        from
            film
        where
            title ilike p_pattern;
end;$$

create or replace function get_film_into_variables (
  p_pattern varchar
)
returns null
    language plpgsql
as $$
declare
    v_title varchar,
    v_release_year integer
begin
    SELECT
        get_film (p_pattern)
    INTO
        v_title,
        v_release_year;

end;$$

标签: sqlpostgresql

解决方案


假设您在检索变量后对变量有一些用途,而不仅仅是结束函数,您的“get_film_into_variables”几乎就在那里。但首先让我们备份一下。返回表的函数就是这样做的,您可以像使用存储在磁盘上的表一样使用结果(它只是在查询或调用函数结束后消失)。为此,只需对“get_film_into_variables”函数稍作改动。“get_film”成为 FROM 子句的对象。还将返回 null 更改为返回 void。所以

create or replace function get_film_into_variables (
  p_pattern varchar
)
returns void
    language plpgsql
as $$
declare
    v_title varchar;
    v_release_year integer;

begin
    select *
      from get_film (p_pattern)
    INTO
        v_title,
        v_release_year;
end;
$$;

以上适用于函数返回表返回的单行。但是,对于多行的返回,您只需处理表返回函数的结果,您就会得到一个实际的表 - 带有游标。

create or replace 
function get_film_into_variables2(p_pattern varchar)
  returns void
  language plpgsql
as $$
declare
    k_message_template constant text = 'The film "%s" was released in %s.';
    v_title varchar;
    v_release_year integer;
    v_film_message varchar; 
   
    c_film  cursor (c_pattern varchar) for
        select * from  get_film (c_pattern);
      
begin    
    open c_film (p_pattern);
    loop
        fetch c_film
         into v_title 
            , v_release_year;  
        exit when not found;

        v_film_message = format( k_message_template,v_title,v_release_year::text);
        raise notice using
           message = v_film_message;
      
    end loop;
end;
$$;

顺便说一句:get_film 函数可以转换为 SQL 函数。在这里看小提琴。出于演示目的,get_film_into_variable 例程返回一条消息。


推荐阅读