使用函数执行具有不同数据类型的多个 select 语句

Executing multiple select statements with different data types using functions

如何使用 postgresql 中的函数执行具有不同数据类型的多个 select 语句?

CREATE OR REPLACE FUNCTION multiple3()
  RETURNS TABLE(a text, b text, c character varying, d character varying, e character varying, f character varying, g character varying,h character varying) AS
$BODY$
BEGIN

RETURN QUERY select a,b,c from table 1;

RETURN QUERY select e,f,g,h from table 2;

END
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100
  ROWS 1000;


-- here a and e are different data types

您不能 return 来自 plpgsql 函数的具有不同数据类型的行,因为一次调用中的所有 returned 值必须属于同一类型。

如果您想要 return 列的行数可变,您应该将 recordsetof record 声明为函数的 return 类型。 但是,在这种情况下,您必须在函数调用中指定预期的行结构。

函数 returning 一行应该有 record 作为 returned 类型。示例:

create or replace function test_record(number_of_columns int)
returns record language plpgsql as $$
begin
    case number_of_columns
        when 1 then 
            return row('a'::text);
        when 2 then 
            return row('a'::text, 2::integer);
        else 
            return row('a'::text, 2::integer, 5.5::numeric);
    end case;
end $$;

执行查询时,您必须知道函数 returns:

有多少列
select * from test_record(1) as (column1 text);

 column1 
---------
 a

select * from test_record(2) as (column1 text, column2 integer);

 column1 | column2 
---------+---------
 a       |       2

select * from test_record(3) as (column1 text, column2 integer, column3 numeric);

 column1 | column2 | column3 
---------+---------+---------
 a       |       2 |     5.5

-- but:

select * from test_record(3) as (column1 text);
ERROR:  returned record type does not match expected record type
DETAIL:  Number of returned columns (3) does not match expected column count (1).
CONTEXT:  PL/pgSQL function test_record(integer) while casting return value to function's return type

return超过一行的函数应具有 setof record 作为 returned 类型:

create or replace function test_set_of_record(number_of_columns int)
returns setof record language plpgsql as $$
begin
    case number_of_columns
        when 1 then 
            return query select i::text from generate_series(1, 3) i;
        when 2 then 
            return query select i::text, i from generate_series(1, 3) i;
        else 
            return query select i::text, i, i::numeric from generate_series(1, 3) i;
    end case;
end $$;

select * from test_set_of_record(3) as (column1 text, column2 integer, column3 numeric);

 column1 | column2 | column3 
---------+---------+---------
 1       |       1 |       1
 2       |       2 |       2
 3       |       3 |       3
(3 rows)

阅读更多:7.2.1.4. Table Functions.

另一种选择是使用 null 值使行适合 returned 类型,例如:

create or replace function test_with_nulls()
returns table (col1 text, col2 int, col3 numeric)
language plpgsql as $$
begin
    return query select 'one'::text, null::int, null::numeric;
    return query select 'two'::text, 2::int, null::numeric;
    return query select 'three'::text, 3::int, 3.3::numeric;
end $$;

select * from test_with_nulls();

 col1  | col2 | col3 
-------+------+------
 one   |      |     
 two   |    2 |     
 three |    3 |  3.3
(3 rows)