E 'possibile restituire più set di risultati da una funzione Postgres, come in MSSQL:funzione di PostgreSQL tornare risultato più set
CREATE PROCEDURE test
AS
SELECT * FROM first_table
SELECT * FROM second_table
E 'possibile restituire più set di risultati da una funzione Postgres, come in MSSQL:funzione di PostgreSQL tornare risultato più set
CREATE PROCEDURE test
AS
SELECT * FROM first_table
SELECT * FROM second_table
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)
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 :)
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
.]
Nitpicking, ma UNION ALL sarebbe più veloce (non esiste "| sort | uniq"), ma restituirà duplicati se ce ne sono. – tommym
@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.) –
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
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.
cosa per i diversi tipi di riga? c'è qualche soluzione? diverso dal cursore. Sto cercando di ottenere due recordset su una sola chiamata. –
@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. –
Si utilizza solo 1 tabella, la tabella "cliente". La domanda riguarda più set di risultati! – llouk