如何使用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
答案 0 :(得分:1)
您不能从plpgsql函数返回具有不同数据类型的行,因为一次调用中的所有返回值必须属于同一类型。
如果要返回具有可变列数的行,则应将record
或setof record
声明为函数的返回类型。
但是,在这种情况下,您必须在函数调用中指定预期的行结构。
返回一行的函数应该以{{1}}作为返回类型。例如:
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 $$;
返回多行的函数应该以{{1}}作为返回类型:
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
了解详情:7.2.1.4. Table Functions。
另一种选择是使用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)