从PostgreSQL函数返回复合类型或多列

从PostgreSQL函数返回复合类型或多列,sql,postgresql,types,plpgsql,return-type,Sql,Postgresql,Types,Plpgsql,Return Type,我的目标是编写一个函数,它接受一个参数并返回两个值。查询工作正常,但是,当通过made函数执行时,我收到一个错误,即子查询不应返回多个列 我的职能如下: 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 d

我的目标是编写一个函数,它接受一个参数并返回两个值。查询工作正常,但是,当通过made函数执行时,我收到一个错误,即子查询不应返回多个列

我的职能如下:

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 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);
我得到以下错误:


您可以通过对复合类型进行显式转换来修复语法错误:

CREATE OR REPLACE FUNCTION next_dvd_in_queue (member_id_p1 integer)
  RETURNS double_integer_type AS
$func$
BEGIN
   RETURN (
       SELECT ROW(temp2.dvdid, temp2.movie_title)::double_integer_type
       FROM  ...
   );
END
$func$  LANGUAGE plpgsql
避免参数名和列名之间的命名冲突。我喜欢坚持一种命名约定,即在所有参数名称前面加上
\uu
,因此
\umember\uid\up1
\up1
\up2

相关的:


谢谢你,欧文!
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
CREATE OR REPLACE FUNCTION next_dvd_in_queue (member_id_p1 integer)
  RETURNS double_integer_type AS
$func$
BEGIN
   RETURN (
       SELECT ROW(temp2.dvdid, temp2.movie_title)::double_integer_type
       FROM  ...
   );
END
$func$  LANGUAGE plpgsql
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;