web-dev-qa-db-ja.com

PostgreSQLストアドプロシージャから結果セットを返す方法は?

PostgreSQLはバージョン11以降のストアドプロシージャ(関数ではない)をサポートしています。次のようなストアドプロシージャを作成しました。

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

しかし、この保存されたプロシージャを実行しようとすると、データが返されません。

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.

したがって、問題は、ストアドプロシージャがPostgreSQL11以降でその結果セットをどのように返すことができるかということです。

4
Fong-Wan Chau

Postgres 11(太字の強調鉱山)でdocsに続いて:

プロシージャには戻り値がありません。したがって、プロシージャはRETURNステートメントなしで終了できます。コードを早期に終了するためにRETURNステートメントが必要な場合は、NULLを返す必要があります。他の値を返すとエラーになります。

ただし、パラメーターを出力としてマークして、変数のように動作させることもできます。

ちなみに、他のDBMSには通常、関数がSELECTステートメントのみを呼び出すことができ、プロシージャがデータ操作およびデータ定義言語(DML、DDL)を処理する必要がある間、データを変更してはならないという違いがあります。これは、(私の意見では)単に安定した(*)selectステートメントを実行するプロシージャを作成することは望ましい手法ではないと結論付けています。

(*)関数のボラティリティについてもっと読む ここ

3