2

How can I execute multiple select statements with different data types using functions in postgresql?

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
1
  • Your question is not clear. Add a description what you want to achieve exactly and a small example of the exact output you expect. Commented Oct 8, 2015 at 20:17

1 Answer 1

1

You cannot return rows with different data types from plpgsql function in the sense that all returned values in one call must be of the same type.

If you want to return rows with variable number of columns you should declare record or setof record as return type of the function. In this case however you have to specify expected row structure in the function call.

Functions returning one row should have record as returned type. Example:

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

When executing a query you have to know how many columns the function 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

Functions returning more than one row should have setof record as returned type:

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)

Read more: 7.2.1.4. Table Functions.

Another option is to use null values to fit a row to returned type, example:

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)
Sign up to request clarification or add additional context in comments.

1 Comment

I think you don't need SELECT * FROM function(...) but SELECT function(...) is enough. See postgresql.org/docs/9.1/static/sql-syntax-calling-funcs.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.