如何从postgresql函数返回表的不确定数字列?

时间:2014-01-14 01:59:18

标签: postgresql types plpgsql

我们知道,plpgsql函数可以返回如下表:

RETURNS table(int, char(1), ...)

但是当创建函数时列的列表不确定时,如何编写此函数。

2 个答案:

答案 0 :(得分:1)

如果结果是不确定/未定义的格式,您必须使用RETURNS record或(对于多行结果)RETURNS SETOF record

然后调用函数必须指定表格格式,例如:

SELECT my_func() AS result(a integer, b char(1));

BTW,char是一种糟糕的数据类型,具有疯狂的空间填充规则,可以追溯到固定宽度文件格式的日子。不要使用它。始终只使用textvarchar

鉴于评论,让我们明确地说明这一点:

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。你可能没有仔细阅读他的答案。

根据您的具体需要,有很多方法可以解决这个问题

1)返回单个匿名记录

示例:

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

2)使用超级列

返回众所周知的行类型

示例:

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展示所有。

3)高级解决方案

这个答案已经足够长了。这个密切相关的答案有这一切:
Refactor a PL/pgSQL function to return the output of various SELECT queries

特别关注最后一章:各种完整的表格类型