我们知道,plpgsql函数可以返回如下表:
RETURNS table(int, char(1), ...)
但是当创建函数时列的列表不确定时,如何编写此函数。
答案 0 :(得分:1)
如果结果是不确定/未定义的格式,您必须使用RETURNS record
或(对于多行结果)RETURNS SETOF record
。
然后调用函数必须指定表格格式,例如:
SELECT my_func() AS result(a integer, b char(1));
BTW,char
是一种糟糕的数据类型,具有疯狂的空间填充规则,可以追溯到固定宽度文件格式的日子。不要使用它。始终只使用text
或varchar
。
鉴于评论,让我们明确地说明这一点:
regress=> CREATE OR REPLACE FUNCTION f_something() RETURNS SETOF record AS $$
SELECT 1, 2, TEXT 'a';
$$ LANGUAGE SQL;
CREATE FUNCTION
regress=> SELECT * FROM f_something();
ERROR: a column definition list is required for functions returning "record"
LINE 1: SELECT * FROM f_something();
regress=> SELECT * FROM f_something() AS x(a integer, b integer, c text);
a | b | c
---+---+---
1 | 2 | a
(1 row)
答案 1 :(得分:0)
当函数返回匿名记录时
RETURNS SETOF record
必须在使用SELECT * FROM
进行调用时提供列定义列表。 SQL要求了解列名称和类型以解释 *
。对于已注册的表和类型,这由系统目录提供。对于函数,您需要自己声明以某种方式。在函数定义或调用中。通话可能看起来像@Craig already provided。你可能没有仔细阅读他的答案。
根据您的具体需要,有很多方法可以解决这个问题:
示例:
CREATE OR REPLACE FUNCTION myfunc_single() -- return a single anon rec
RETURNS record AS
$func$
DECLARE
rec record;
BEGIN
SELECT into rec 1, 'foo'; -- note missing type for 'foo'
RETURN rec;
END
$func$ LANGUAGE plpgsql;
这是一个非常有限的利基。仅适用于使用以下函数定义的函数中的单个匿名记录:
RETURNS record
不使用* FROM
致电
SELECT myfunc_single();
不适用于SRF(设置返回函数),只返回整个记录的字符串表示形式(类型record
)。很少有用。
要从单个匿名记录中获取单个cols,您需要再次提供列定义列表:
SELECT * FROM myfunc_single() AS (id int, txt unknown); -- note "unknown" type
示例:
CREATE TABLE t (id int, txt text, the_date date);
INSERT INTO t VALUES (3, 'foz', '2014-01-13'), (4, 'baz', '2014-01-14');
CREATE OR REPLACE FUNCTION myfunc_tbl() -- return well known table
RETURNS SETOF t AS
$func$
BEGIN
RETURN QUERY
TABLE t;
-- SELECT * FROM t; -- equivalent
END
$func$ LANGUAGE plpgsql;
该函数返回表的所有列。这是简短而简单的,只要您的表没有大量的列或大列,性能就不会受到影响。
选择待处理的各个列:
SELECT id, txt FROM myfunc_tbl();
SELECT id, the_date FROM myfunc_tbl();
-> SQLfiddle展示所有。
这个答案已经足够长了。这个密切相关的答案有这一切:
Refactor a PL/pgSQL function to return the output of various SELECT queries
特别关注最后一章:各种完整的表格类型