代码之家  ›  专栏  ›  技术社区  ›  puk

Postgres函数将表返回到变量中

  •  0
  • puk  · 技术社区  · 4 年前

    如何将不同的列捕获到不同的变量中(注意,这只是伪代码,所以我假设它会导致错误) here )

    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;$$
    
    0 回复  |  直到 4 年前
        1
  •  1
  •   Belayer    4 年前

    假设您在检索变量后对它们有了某种用途,而不仅仅是结束函数,那么“get_film_into_variables”(获取变量)就快到了。但首先让我们备份一下。一个返回表的函数就是这样做的,您可以像使用存储在磁盘上的表一样使用结果(它只是在查询或调用函数结束后消失)。为此,只需对“get_film_into_variables”函数稍作修改。“get_film”成为FROM子句的对象。还可以将returns null更改为returns 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函数。看小提琴 here .为了演示的目的,让电影进入变量例程,并返回一条消息。