2009-04-16 11 views

risposta

-1

Sì.

Esempio:

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) 

Ovviamente si può utilizzare una tabella/vista esistente o di un tipo personalizzato per il tipo restituito.

Esempio utilizzando il linguaggio 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

Si utilizza solo 1 tabella, la tabella "cliente". La domanda riguarda più set di risultati! – 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. utilizzando refcursors :)

+2

Inserendo questo ai miei tavoli ottengo: 'SELECT [* FROM]" pr_GetCustomersAndOrders "(); pr_GetCustomersAndOrders -------------------------- ' Utilizzo di psql 9.1. – valid

+2

Lo stesso vale anche per – llouk

3

Se first_table e second_table hanno lo stesso layout, si può anche semplicemente usare

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

[EDIT: Grazie ad un commentatore (il cui nome non è probabilmente "null" :)) per sottolineando che UNION ALL è più veloce di UNION.]

+3

Nitpicking, ma UNION ALL sarebbe più veloce (non esiste "| sort | uniq"), ma restituirà duplicati se ce ne sono. – tommym

+1

@null: buon punto; aggiornato. (Mi rendo conto che il tuo nome probabilmente non è "null" - sembra che un recente SO bug lo abbia causato. Sono riuscito a correggerlo modificando il campo superiore nella pagina del mio profilo.) –

+3

Sì, ma per quanto riguarda le query che non vengono restituite gli stessi layout? È piuttosto limitativo se abbiamo bisogno di ottenere molti set. Utilizzo stored procedure in SQL Server che restituisce oltre 10 set di risultati. Qualcosa del genere in PostgreSQL? – MaxiWheat

13

Un modo più semplice è stato intorno dal PostgreSQL 8.3 (molto prima che t la sua domanda è stato chiesto):!

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; 

chiamata:

SELECT * FROM test(); 

Vedere le manual on RETURN QUERY.

+1

cosa per i diversi tipi di riga? c'è qualche soluzione? diverso dal cursore. Sto cercando di ottenere due recordset su una sola chiamata. –

+1

@UdeetSolanki: impossibile come risultato diretto da una funzione. Ci sono vari modi per aggirarlo: con cursori, tabelle temporanee, tipi di documenti come 'json'. Ti suggerisco di fare una nuova domanda, i commenti non sono il posto. –

Problemi correlati