Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the easiest way to return a recordset from a PostgreSQL stored procedure?

I simply have a table that contains a list of countries and their ISO country codes. I'm wrapping the query in a stored procedure (aka function) such as:

CREATE OR REPLACE FUNCTION get_countries(
                    ) RETURNS setof record AS $$
        SELECT country_code, country_name FROM country_codes
$$ LANGUAGE sql;

The error I am getting is:

ERROR:  a column definition list is required for functions returning "record"

I know that I can define a TYPE and then loop through the recordset like a cursor, but IIRC there's a better way to do this under newer versions of PostgreSQL (I'm using 8.4.3) but I'm pulling my hair out trying to remember.


Edit:

This works:

CREATE OR REPLACE FUNCTION get_countries(
                    ) RETURNS setof country_codes AS $$
        SELECT country_code, country_name FROM country_codes
$$ LANGUAGE sql;

Note the "RETURNS setof [table name]". But it doesn't seem to be the most flexible. It falls apart if I attempt to return a join of several tables.

like image 286
jamieb Avatar asked Jan 10 '10 04:01

jamieb


People also ask

How do you return a table from a stored procedure in Postgres?

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.

Can we return value from stored procedure in PostgreSQL?

In case you want to return a value from a stored procedure, you can use output parameters. The final values of the output parameters will be returned to the caller.

How can we return a value in stored procedure?

The RETURN statement is used to unconditionally and immediately terminate an SQL procedure by returning the flow of control to the caller of the stored procedure. It is mandatory that when the RETURN statement is executed that it return an integer value. If the return value is not provided, the default is 0.

How do I return a ref cursor in PostgreSQL?

Declaring cursorsPostgreSQL provides you with a special type called REFCURSOR to declare a cursor variable. First, you specify a variable name for the cursor. Next, you specify whether the cursor can be scrolled backward using the SCROLL . If you use NO SCROLL , the cursor cannot be scrolled backward.


2 Answers

There is also the option of using RETURNS TABLE(...) (as described in the PostgreSQL Manual), which I personally prefer:

CREATE OR REPLACE FUNCTION get_countries()
RETURNS TABLE(
    country_code text,
    country_name text
)
AS $$
    SELECT country_code, country_name FROM country_codes
$$ LANGUAGE sql;

This is effectively the same as using SETOF tablename, but declares the table structure inline instead of referencing an existing object, so joins and such will still work.

like image 134
codermonkeyfuel Avatar answered Oct 12 '22 22:10

codermonkeyfuel


You should be able to use output parameters, like this:

CREATE OR REPLACE FUNCTION get_countries(country_code OUT text, country_name OUT text)
RETURNS setof record
AS $$ SELECT country_code, country_name FROM country_codes $$
LANGUAGE sql;
like image 23
Magnus Hagander Avatar answered Oct 12 '22 23:10

Magnus Hagander