web-dev-qa-db-fra.com

Fonctions PL/pgSQL: Comment retourner une table avec une instruction execute

J'ai cette PL/pgSQL fonction qui doit retourner des informations à certains utilisateurs.

CREATE OR REPLACE FUNCTION my_function(user_id integer)
  RETURNS TABLE(id integer, firstname character varying
                          , lastname  character varying) AS
$$
DECLARE
    ids character varying;
BEGIN
    ids := '';

    --Some code which build the ids string, not interesting for this issue

    RETURN QUERY EXECUTE 'SELECT users.id, users.firstname, users.lastname
    FROM public.users WHERE ids IN (' || ids || ')';
END;
$$ LANGUAGE plpgsql;

Le problème auquel je suis confronté est que le résultat de la fonction est un tableau à une seule colonne, comme ceci:

╔═══╦═════════════════════╗
║   ║my_function          ║
╠═══╬═════════════════════╣
║ 1 ║ (106,Ned,STARK)     ║
║ 2 ║ (130,Rob,STARK)     ║
╚═══╩═════════════════════╝

Alors que j'attendais:

╔═══╦════════════╦════════════╦═════════════╗
║   ║ id         ║ firstname  ║ lastname    ║
╠═══╬════════════╬════════════╬═════════════╣
║ 1 ║ 106        ║ Ned        ║ STARK       ║
║ 2 ║ 103        ║ Rob        ║ STARK       ║
╚═══╩════════════╩════════════╩═════════════╝

Je pense (mais je ne suis pas sûr) que le problème vient de la déclaration EXECUTE, mais je ne vois pas comment faire autrement.

Des idées?

23
Getz

Comment exécutez-vous cette fonction? Cela fonctionne comme une instruction select.

Créer une table: public.users

create table public.users (id int, firstname varchar, lastname varchar);

Insérer quelques enregistrements:

insert into public.users values (1, 'aaa','bbb'),(2,'ccc','ddd');

fonction: ma_fonction

CREATE OR REPLACE FUNCTION my_function(user_id integer) RETURNS TABLE(id integer, firstname character varying, lastname character varying) AS $$
    DECLARE
        ids INTEGER[];
    BEGIN
         ids := ARRAY[1,2];
         RETURN QUERY
             SELECT users.id, users.firstname, users.lastname
             FROM public.users
             WHERE users.id = ANY(ids);
    END;
$$ LANGUAGE plpgsql;

Maintenant, vous pouvez utiliser avec *

select * from my_function(1);

Résultat de la requête

 id | firstname | lastname 
----+-----------+----------
  1 | aaa       | bbb
  2 | ccc       | ddd

Ou avec des noms de colonne aussi

select id,firstname,lastname from my_function(1);

Résultat 

 id | firstname | lastname 
----+-----------+----------
  1 | aaa       | bbb
  2 | ccc       | ddd
33
bma

Appelez la fonction comme ça: 

select * from  my_function(123);

Pas seulement avec select. J'ai fait et ça marche

2
selin kamaş

http://www.postgresqltutorial.com/plpgsql-function-returns-a-table/

il y a une différence dans la sortie reçue de la fonction en fonction de la syntaxe de la sélection:

select * from myfunction();

et

select myfunction();
0
Skysnake