2010-12-29 2 views
1

Je souhaite écrire une procédure stockée qui renvoie un objet 'aplati'. En 'aplatissant', je sélectionne essentiellement un ensemble de lignes, et retourne des champs spécifiques dans les lignes, dans les données renvoyées par la fonction.Comment écrire cette fonction pl/pgsql?

Le code ci-dessous explique ce que je suis en train de faire

CREATE TABLE user (id int, school_id int, name varchar(32)); 

CREATE TYPE my_type (user1_id int, user1_name varchar(32), user2_id int, user2_name varchar(32)); 

CREATE OR REPLACE FUNCTION get_two_users_from_school(schoolid int) 
RETURNS my_type AS $$ 
DECLARE 
result my_type 
temp_result user 
BEGIN 
    -- for purpose of this question assume 2 rows returned 
    SELECT id, name INTO temp_result FROM user where school_id = schoolid LIMIT 2; 
    -- Will the (pseudo)code below work?: 
    result.user1_id := temp_result[0].id ; 
    result.user1_name := temp_result[0].name ; 
    result.user2_id := temp_result[1].id ; 
    result.user2_name := temp_result[1].name ; 
    return result ; 
END 
$$ language plpgsql 

J'ai deux questions:

  • Suis-je utiliser le type de données correct pour temp_result variables
  • Suis-je accéder aux lignes correctement (en utilisant l'indexation de tableau)?

Répondre

1

Est-ce que j'accède aux lignes correctement (en utilisant l'indexation de tableau)?

Non, vous devez faire une boucle par le résultat à l'aide d'un curseur qui est bien expliqué dans le manuel: http://www.postgresql.org/docs/current/static/plpgsql-control-structures.html#PLPGSQL-RECORDS-ITERATING

Quelque chose comme cela devrait fonctionner:

 
DECLARE 
    temp_result RECORD; 
    row_counter integer; 
BEGIN 
    row_counter := 1; 
    FOR temp_result IN SELECT id, name FROM user where school_id = schoolid LIMIT 2 LOOP 
    IF row_counter = 1 THEN 
     result.user1_id := temp_result.id; 
     result.user1_name = temp_result.name; 
    END IF; 
    IF row_counter = 2 THEN 
     result.user2_id := temp_result.id; 
     result.user2_name = temp_result.name; 
    END IF; 
    row_counter := row_counter + 1; 
    END LOOP; 

    return result; 
END; 

BTW: ayant une table nommé "utilisateur" n'est pas une très bonne idée car l'utilisateur est un mot réservé et pourrait causer quelques problèmes à long terme.

+0

Les noms de tables sont juste pour l'exemple ici :) – skyeagle