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.
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.
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.
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.
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.
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.
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With