使用函数执行具有不同数据类型的多个 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 列的行数可变,您应该将 record
或 setof 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)
如何使用 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 列的行数可变,您应该将 record
或 setof 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)