Si par "basé sur une table connue" vous voulez dire "exactement comme une table connue", alors oui .
SQL est un langage strictement typé et les fonctions doivent être créées avec un type de retour bien défini. Vous pouvez revenir aux enregistrements anonymes comme vous l'avez évidemment fait (avec RETURNS SETOF record
), mais vous devez ensuite ajouter une liste de définition de colonne pour chaque appel, comme le message d'erreur vous l'indique. Quelque chose comme :
SELECT *
FROM my_function('foo') AS foo (
colum_name1 integer -- name and data type for every column
, colum_name2 text
, colum_name3 real);
Et ce n'est guère dynamique.
Votre question laisse place à interprétation, mais "basée sur un tableau connu" indiquerait qu'une fonction polymorphe pourrait faire l'affaire. Le type de retour peut être basé sur n'importe quel type de ligne enregistré de manière dynamique, et il en existe automatiquement un pour chaque table du système. Exemple de code Barebone :
CREATE OR REPLACE FUNCTION my_function(_rowtype anyelement)
RETURNS SETOF anyelement AS
$func$
BEGIN
RETURN QUERY EXECUTE format(
'SELECT * FROM %s LIMIT 10'
, pg_typeof(_rowtype) -- pg_typeof() returns regtype, quoted where necessary
);
END
$func$ LANGUAGE plpgsql;
Appel :
SELECT * FROM my_function(NULL::my_table);
Instructions détaillées dans cette réponse connexe (consultez le dernier chapitre "Divers types de tableaux complets" ):