Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PL/pgSQL functions: How to return a normal table with multiple columns using an execute statement

I've got this PL/pgSQL function which must return some users information.

CREATE OR REPLACE FUNCTION my_function(         user_id integer     ) RETURNS TABLE(             id integer,              firstname character varying,             lastname  character varying         ) AS $$     DECLARE         ids character varying;     BEGIN         ids := '';         --Some code which build the ids string, not interesting for this issue         RETURN QUERY              EXECUTE 'SELECT                          users.id,                          users.firstname,                          users.lastname                     FROM public.users                      WHERE ids IN (' || ids || ')';     END; $$ LANGUAGE plpgsql; 

The problem I'm facing is that the result of the function is a single columns table like this:

╔═══╦═════════════════════╗ ║   ║my_function          ║ ╠═══╬═════════════════════╣ ║ 1 ║ (106,Ned,STARK)     ║ ║ 2 ║ (130,Rob,STARK)     ║ ╚═══╩═════════════════════╝ 

While I expected:

╔═══╦════════════╦════════════╦═════════════╗ ║   ║ id         ║ firstname  ║ lastname    ║ ╠═══╬════════════╬════════════╬═════════════╣ ║ 1 ║ 106        ║ Ned        ║ STARK       ║ ║ 2 ║ 103        ║ Rob        ║ STARK       ║ ╚═══╩════════════╩════════════╩═════════════╝ 

I think (but not sure) the problem comes from the EXECUTE statement, but I can't see how to do otherwise.

Any ideas?

like image 425
Getz Avatar asked Aug 06 '13 15:08

Getz


People also ask

How do you create a PL pgSQL function that returns a table?

syntax: CREATE [OR REPLACE] FUNCTION function_name (arguments) RETURNS name_of_return_datatype AS $variable_name$ DECLARE declaration; BEGIN [ function_body ] RETURN { variable_name | value } END; LANGUAGE plpgsql; Where, function-name: It is used to specify the name of the function.

Can we return table from function in PostgreSQL?

To return a table from the function, you use RETURNS TABLE syntax and specify the columns of the table. Each column is separated by a comma (, ). In the function, we return a query that is a result of a SELECT statement.

How do I SELECT multiple columns in PostgreSQL?

If you specify a list of columns, you need to place a comma ( , ) between two columns to separate them. If you want to select data from all the columns of the table, you can use an asterisk ( * ) shorthand instead of specifying all the column names.

How do I return multiple result sets in PostgreSQL?

A simpler way has been around since PostgreSQL 8.3: CREATE FUNCTION test() RETURNS SETOF first_table AS $func$ BEGIN RETURN QUERY SELECT * FROM first_table; RETURN QUERY SELECT * FROM second_table; -- has to return same rowtype as first_table!


2 Answers

How are you executing that function? It works as a select statement.

Create a table: public.users

create table public.users (id int, firstname varchar, lastname varchar); 

Insert some records:

insert into public.users values (1, 'aaa','bbb'),(2,'ccc','ddd'); 

function: my_function

CREATE OR REPLACE FUNCTION my_function(user_id integer) RETURNS TABLE(id integer, firstname character varying, lastname character varying) AS $$     DECLARE         ids INTEGER[];     BEGIN          ids := ARRAY[1,2];          RETURN QUERY              SELECT users.id, users.firstname, users.lastname              FROM public.users              WHERE users.id = ANY(ids);     END; $$ LANGUAGE plpgsql; 

Now you can use with *

select * from my_function(1); 

Result of query

 id | firstname | lastname  ----+-----------+----------   1 | aaa       | bbb   2 | ccc       | ddd 

Or with column names as well

select id,firstname,lastname from my_function(1); 

Result

 id | firstname | lastname  ----+-----------+----------   1 | aaa       | bbb   2 | ccc       | ddd 
like image 192
bma Avatar answered Oct 02 '22 12:10

bma


Call function like that :

select * from  my_function(123); 

Not just with select. I did and It works

like image 37
selin kamaş Avatar answered Oct 02 '22 10:10

selin kamaş