Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return result set from PostgreSQL stored procedure?

PostgreSQL supports stored procedure (not function) since version 11. I created a stored procedure like this:

CREATE OR REPLACE PROCEDURE get_user_list ()
  LANGUAGE SQL
  SECURITY DEFINER
  AS $$
  SELECT "id",
         "username",
         "display_name"
  FROM "user"
  ORDER BY "created_at" ASC;
$$;

But when I am trying to execute this stored procedure, it does not return any data:

postgres=# CALL get_user_list();
CALL
postgres=# SELECT * FROM get_user_list();
ERROR:  get_user_list() is a procedure
LINE 1: SELECT * FROM get_user_list();
                      ^
HINT:  To call a procedure, use CALL.

So the question is, how can a stored procedure returns its result set in PostgreSQL 11+?

like image 498
Fong-Wan Chau Avatar asked Jun 17 '18 06:06

Fong-Wan Chau


People also ask

Can PostgreSQL stored procedure return resultset?

However, as of Postgres 11, you can return result sets from a PostgreSQL Procedure using cursors, though it can be tedious to iterate over the results.

What is result set in stored procedure?

In addition to returning output parameters, a stored procedure can return a result set (that is, a result table associated with a cursor opened in the stored procedure) to the application that issues the CALL statement. The application can then issue fetch requests to read the rows of the result set cursor.

What is Refcursor in PostgreSQL?

PostgreSQL provides you with a special type called REFCURSOR to declare a cursor variable.


1 Answers

Following the docs on Postgres 11 (bold emphasis mine):

A procedure does not have a return value. A procedure can therefore end without a RETURN statement. If a RETURN statement is desired to exit the code early, then NULL must be returned. Returning any other value will result in an error.

You could mark your parameters as output though, so that they would behave like variables.

On a side note there's normally a distinction within other DBMS that functions can only call SELECT statements and should not modify data while procedures should be handling the data manipulation and data definition languages (DML, DDL). This concludes (in my opinion) that creating a procedure to simply perform a stable (*) select statement is not the desired technique.

(*) Read more on function volatility here.

like image 184
Kamil Gosciminski Avatar answered Sep 19 '22 03:09

Kamil Gosciminski