Как написать эту функцию pl / pgsql? - PullRequest
1 голос
/ 29 декабря 2010

Я хочу написать хранимую процедуру, которая возвращает «плоский» объект.Под «выравниванием» я в основном выбираю набор строк и возвращаю конкретные поля в строках в данные, возвращаемые функцией.

Приведенный ниже код объясняет, что я пытаюсь сделать

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

У меня два вопроса:

  • Использую ли я правильный тип данных для переменной temp_result
  • Правильно ли я получаю доступ к строкам (используя индексацию массива)?

1 Ответ

1 голос
/ 29 декабря 2010

Правильно ли я обращаюсь к строкам (используя индексацию массива)?

Нет, вам нужно перебрать результат с помощью курсора, который хорошо объясняется в руководстве: http://www.postgresql.org/docs/current/static/plpgsql-control-structures.html#PLPGSQL-RECORDS-ITERATING

Примерно так должно работать:

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;

Кстати: иметь таблицу с именем «user» не очень хорошая идея, так как user является зарезервированным словом и может вызвать некоторые проблемы в долгосрочной перспективе.

...