Возвращает составной тип или несколько столбцов из функции PostgreSQL - PullRequest
0 голосов
/ 21 апреля 2020

Моя цель - написать функцию, которая принимает один параметр и возвращает два значения. Запрос работает отлично, однако при выполнении через созданную функцию я получаю сообщение об ошибке, что подзапрос не должен возвращать несколько столбцов.

Моя функция выглядит следующим образом:

CREATE TYPE double_integer_type AS (p1 integer, p2 integer);

DROP FUNCTION next_dvd_in_queue;

CREATE OR REPLACE FUNCTION next_dvd_in_queue (member_id_p1 integer) RETURNS double_integer_type as $$
BEGIN
RETURN(
    select temp2.dvdid,
       temp2.movie_title
from
    (select temp1.dvdid,
            temp1.movie_title,
            temp1.customer_priority
     from
         (select *
          from rentalqueue
          where rentalqueue.memberid=member_id_p1) temp1
     inner join dvd on dvd.dvdid=temp1.dvdid
     where dvd.dvdquantityonhand>0) temp2
order by temp2.customer_priority asc
limit 1
);
END; $$ LANGUAGE PLPGSQL

Вызов :

select dvdid from next_dvd_in_queue(3);

Запрос, если он выполняется с жестко заданным значением:

select temp2.dvdid,
       temp2.movie_title
from
    (select temp1.dvdid,
            temp1.movie_title,
            temp1.customer_priority
     from
         (select *
          from rentalqueue
          where rentalqueue.memberid=3) temp1
     inner join dvd on dvd.dvdid=temp1.dvdid
     where dvd.dvdquantityonhand>0) temp2
order by temp2.customer_priority asc
limit 1

Вышеупомянутый запрос работает нормально.

Однако, когда я вызываю функция следующим образом:

select * from next_dvd_in_queue(3);

Я получаю следующую ошибку:

ERROR:  subquery must return only one column
LINE 1: SELECT (
               ^
QUERY:  SELECT (
    select temp2.dvdid,
       temp2.movie_title
from
    (select temp1.dvdid,
            temp1.movie_title,
            temp1.customer_priority
     from
         (select *
          from rentalqueue
          where rentalqueue.memberid=3) temp1
     inner join dvd on dvd.dvdid=temp1.dvdid
     where dvd.dvdquantityonhand>0) temp2
order by temp2.customer_priority asc
limit 1
)
CONTEXT:  PL/pgSQL function next_dvd_in_queue(integer) line 3 at RETURN

1 Ответ

1 голос
/ 21 апреля 2020

Вы можете исправить синтаксическую ошибку с помощью явного приведения к составному типу:

CREATE OR REPLACE FUNCTION next_dvd_in_queue (member_id_p1 integer)
  RETURNS double_integer_type AS
$func$
BEGIN
   RETURN (
       SELECT <b>ROW(temp2.dvdid, temp2.movie_title)::double_integer_type</b>
       FROM  ...
   );
END
$func$  LANGUAGE plpgsql

Но я бы удалил ненужные сложности с составным типом и использовал бы OUT параметры вместо этого:

CREATE OR REPLACE FUNCTION pg_temp.next_dvd_in_queue (member_id_p1 integer
                                                  OUT p1 integer
                                                  OUT p2 varchar(100)) AS
$func$
BEGIN
   SELECT INTO p1, p2
          temp2.dvdid, temp2.movie_title
   FROM  ...

END
$func$  LANGUAGE plpgsql;

Избегайте коллизий имен между именами параметров и столбцов. Мне нравится придерживаться соглашения об именах, в котором все имена параметров начинаются с префикса _, поэтому _member_id_p1, _p1, _p2.

, относящиеся:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...