问题描述
非常相似的question here,但与此不完全相同。
我有一个函数,它使用 IF
语句来确定要返回的 SELECT
查询类型。
当我永远不知道 CREATE FUNCTION
查询可能返回的确切列时,我如何声明 SELECT
语句应返回的内容?也就是说,我无法使用列列表设置 RETURNS TABLE
声明,因为我不知道哪些列可能会返回。我所知道的是,我肯定希望返回一个结果表。
这是我的函数(未完成,伪):
CREATE OR REPLACE FUNCTION functiona(_url character varying DEFAULT NULL)
RETURNS -- what type? if TABLE how do I kNow what columns to specify
LANGUAGE plpgsql
AS
$$
DECLARE
_urltypeid int;
BEGIN
IF _url IS NOT NULL
THEN
_urltypeid := reference.urltype(_url);
IF _urltypeid = 1
THEN
RETURN QUERY
SELECT location,auxiliary,response FROM tablea -- unique columns from one table
END IF;
IF _urltypeid = 2
THEN
RETURN QUERY
SELECT ip,location,host,authority FROM tableb -- unique columns from another table
END IF;
END IF;
END;
$$;
我来自 MS sql Server 背景,我不必在 CREATE FUNCTION
语句中指定我要返回的内容,因此这对我来说非常混乱。
解决方法
不是答案,而是使用一个简单的例子解释为什么@JonathanJacobson 的答案不起作用:
\d animals
Table "public.animals"
Column | Type | Collation | Nullable | Default
--------+------------------------+-----------+----------+---------
id | integer | | not null |
cond | character varying(200) | | not null |
animal | character varying(200) | | not null |
CREATE OR REPLACE FUNCTION public.animal(a_type character varying)
RETURNS record
LANGUAGE plpgsql
AS $function$
BEGIN
SELECT row(id,cond,animal) FROM animals where animal = a_type;
END;
$function$
select * from animal('cat');
ERROR: a column definition list is required for functions returning "record"
LINE 1: select * from animal('cat');
CREATE OR REPLACE FUNCTION public.animal(a_type character varying)
RETURNS SETOF record
LANGUAGE plpgsql
AS $function$
BEGIN
RETURN QUERY
SELECT id,animal FROM animals where animal = a_type;
END;
$function$
;
select * from animal('cat') as t(i integer,c varchar,a varchar);
i | c | a
---+------+-----
1 | fat | cat
2 | slim | cat
6 | big | cat
为了使用返回 record
或 setof record
的函数的输出,您需要在运行函数时声明输出字段和类型。
您可以使用 record
类型。未测试。
CREATE OR REPLACE FUNCTION functiona(_url character varying DEFAULT NULL)
RETURNS record
LANGUAGE plpgsql
AS
$$
DECLARE
_broadcasttypeid int;
BEGIN
IF _url IS NOT NULL
THEN
_urltypeid := reference.urltype(_url);
IF _urltypeid = 1
THEN
RETURN
(SELECT row(location,auxiliary,response) FROM tablea);
END IF;
IF _urltypeid = 2
THEN
RETURN
(SELECT row(ip,location,host,authority) FROM tableb);
END IF;
END IF;
END;
$$;
其他复合类型,例如 jsonb
和 hstore
也是一种解决方案。