postgresql - 使用函数执行具有不同数据类型的多个选择语句

标签 postgresql plpgsql postgresql-9.3

如何使用 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

最佳答案

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

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

返回一行的函数应将 record 作为返回类型。示例:

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 $$;

执行查询时,您必须知道函数返回多少列:

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

返回多行的函数应将 setof record 作为返回类型:

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 值来使行适合返回的类型,例如:

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)

关于postgresql - 使用函数执行具有不同数据类型的多个选择语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32950142/

相关文章:

postgresql - 连接两个索引表与连接外键之间是否存在性能差异?

sql - 在 PostgreSQL 中按字母顺序对字符串中的字母进行排序

postgresql - PL/pgSQL block 是如何编译的?

c# - 进程中的 pg_dump 未写入任何文件

postgresql - 在 postgresql 中使用 xml 输入时值不匹配

sql - 在 PostgreSQL 中根据时间更新行

sql - postgresql 偏移特定列

sql - PostgreSQL 查询中每个月的最后三个月平均值

postgresql - 在触发器内调用的 postgres 函数中的 select 语句

postgresql - 无法在具有挪威语 (Bokmål) 语言环境的 Postgres 9.3 中创建数据库