Est-il possible de revenir plusieurs jeux de résultats à partir d'une fonction Postgres, comme dans MSSQL:fonction PostgreSQL retour résultat plusieurs jeux
CREATE PROCEDURE test
AS
SELECT * FROM first_table
SELECT * FROM second_table
Est-il possible de revenir plusieurs jeux de résultats à partir d'une fonction Postgres, comme dans MSSQL:fonction PostgreSQL retour résultat plusieurs jeux
CREATE PROCEDURE test
AS
SELECT * FROM first_table
SELECT * FROM second_table
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)
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 :)
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
.]
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
@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.) –
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
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.
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. –
@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. –
Vous utilisez uniquement 1 table, la table "client". La question concerne plusieurs ensembles de résultats! – llouk