PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Un moyen simple d'avoir un type de retour soit une table SETOF plus des champs supplémentaires ?

Vous pourriez renvoie une ligne entière en tant que type composite et en ajoute d'autres :

CREATE OR REPLACE FUNCTION f_rowplus()
  RETURNS TABLE (rec demo, add_int int, add_txt text) AS
$func$
SELECT d, 5, 'baz'::text FROM demo d;
$func$  LANGUAGE sql;

Mais ensuite, lorsque vous utilisez le simple appel :

SELECT * FROM f_rowplus();

Vous obtenez la ligne de la table demo en tant que type composite séparé. Vous devrez appeler :

SELECT (rec).*,  add_int, add_txt FROM f_rowplus();

pour obtenir tous les individuels Colonnes. Parenthèses obligatoires.

Postgres est un peu incohérent ici. Si vous créez une fonction avec :

CREATE OR REPLACE FUNCTION f_row2()
  RETURNS TABLE (rec demo) AS
...

puis le type composite demo est silencieusement convertie en colonnes individuelles (décomposées). Il ne reste aucun lien avec le type composite d'origine. Vous ne pouvez pas référencer la colonne de sortie déclarée rec du tout, puisque cela a été remplacé par les colonnes du type décomposé. Cet appel entraînerait un message d'erreur :

SELECT rec FROM f_row2();

Pareil ici :

CREATE OR REPLACE FUNCTION f_row3(OUT rec demo)
  RETURNS SETOF demo AS
...

Cependant , dès que vous ajoutez tout plus OUT colonnes, le type composite est conservé tel que déclaré (non décomposé) et vous pouvez :

SELECT rec FROM f_rowplus();

avec la première fonction.

J'ai créé un SQL Fiddle démontrant les variantes.

À part
Lors de l'utilisation d'une fonction renvoyant plusieurs colonnes dans le FROM list (comme fonction de table) et décomposition dans le SELECT liste comme ceci :

SELECT (rec).* FROM f_rowplus();

... la fonction est toujours évaluée une fois uniquement - pendant un appel et décomposer dans le SELECT liste directement comme ceci :

SELECT (f_rowplus()).*;  -- also: different result

... évaluerait une fois pour chaque colonne dans le type de retour. Détails :