2009-04-16 7 views

Répondre

-1

Oui.

Exemple:

test=# create function x() returns setof integer language plpgsql as $$ begin return next 1; return next 2; end $$; 
CREATE FUNCTION 
test=# select * from x(); 
x 
--- 
1 
2 
(2 rows) 

Vous pouvez bien sûr utiliser une table/vue existante ou d'un type personnalisé pour le type retourné.

Exemple en utilisant le langage SQL:

test=# create table customer (name varchar, birth_date date); 
CREATE TABLE 
test=# create function y() returns setof customer language sql as $$ 
select * from customer 
union all 
select * from customer 
$$; 
CREATE FUNCTION 
test=# insert into customer values ('joe', now()::date); 
INSERT 0 1 
test=# insert into customer values ('jill', now()::date); 
INSERT 0 1 
test=# select * from y(); 
name | birth_date 
------+------------ 
joe | 2009-04-16 
jill | 2009-04-16 
joe | 2009-04-16 
jill | 2009-04-16 
(4 rows) 

See here for doc

+2

Vous utilisez uniquement 1 table, la table "client". La question concerne plusieurs ensembles de résultats! – llouk

7
CREATE OR REPLACE FUNCTION "pr_GetCustomersAndOrders"() 
RETURNS SETOF refcursor AS 
$BODY$DECLARE 
customerRC refcursor; 
orderRC refcursor; 
BEGIN 
open customerRC FOR 
SELECT * FROM customers; 
RETURN NEXT customerRC; 

open orderRC FOR 
SELECT * FROM orders; 
RETURN NEXT orderRC; 
RETURN; 
END;$BODY$ 
LANGUAGE 'plpgsql' VOLATILE; 
ALTER FUNCTION "pr_GetCustomersAndOrders"() OWNER TO postgres; 

I.o.w. en utilisant refcursors :)

+2

En ajustant cela à mes tables, j'obtiens: 'SELECT [* FROM]" pr_GetCustomersAndOrders "(); pr_GetCustomersAndOrders -------------------------- ' Utilisation de psql 9.1. – valid

+2

Même ici – llouk

3

Si first_table et second_table ont la même mise en page, vous pouvez aussi utiliser

SELECT * FROM first_table WHERE ... 
UNION ALL 
SELECT * FROM second_table WHERE ... 

[EDIT: Merci à un commentateur (dont le nom est probablement pas "null" :)) pour soulignant que UNION ALL est plus rapide que UNION.]

+3

Nitpicking, mais UNION ALL serait plus rapide (il n'y a pas de "| sort | uniq"), mais retournera les doublons s'il y en a. – tommym

+1

@null: Bon point; actualisé. (Je me rends compte que votre nom n'est probablement pas "nul" - il semble qu'un bug SO récent le cause.J'ai été capable de le réparer en éditant le champ supérieur sur ma page de profil.) –

+3

Oui mais qu'en est-il des requêtes qui ne retournent pas les mêmes dispositions? C'est assez limitatif si nous avons besoin de plusieurs jeux. J'utilise avoir une procédure stockée dans SQL Server qui renvoie plus de 10 ensembles de résultats. Quelque chose comme ça dans PostgreSQL? – MaxiWheat

13

Un plus simple façon a été autour depuis PostgreSQL 8.3 (bien avant t sa question a été posée):

CREATE FUNCTION test() 
    RETURNS SETOF first_table AS 
$func$ 
BEGIN 

RETURN QUERY 
SELECT * FROM first_table; 

RETURN QUERY 
SELECT * FROM second_table; -- has to return same rowtype as first_table! 

END 
$func$ LANGUAGE plpgsql; 

Appel:

SELECT * FROM test(); 

Voir la manual on RETURN QUERY.

+1

quoi pour différents types de lignes? y-a-t'il une solution? autre que le curseur. Je cherche à obtenir deux jeux d'enregistrements sur un appel. –

+1

@UdeetSolanki: Pas possible comme résultat direct d'une fonction. Il y a plusieurs façons de le contourner: avec des curseurs, des tables temporaires, des types de documents comme 'json'. Je vous suggère de poser une nouvelle question, les commentaires ne sont pas à la place. –

Questions connexes