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

Moo*_*her 3 postgresql types plpgsql

众所周知,plpgsql 函数可以返回如下表:

RETURNS table(int, char(1), ...)
Run Code Online (Sandbox Code Playgroud)

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

Erw*_*ter 5

当函数返回匿名记录时

RETURNS SETOF record
Run Code Online (Sandbox Code Playgroud)

使用 调用时必须提供列定义列表SELECT * FROM。SQL 要求知道要解释的列名和类型*。对于已注册的表和类型,这是由系统目录提供的。对于函数,您需要自己以一种或另一种方式声明它。无论是在函数定义中还是在调用中。该通话可能看起来像@Craig 已经提供的。你可能没有仔细阅读他的回答。

根据您的具体需求,有多种方法可以解决此问题

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;
Run Code Online (Sandbox Code Playgroud)

这是一个非常有限的利基市场。仅适用于定义为以下函数的单个匿名记录:

RETURNS record
Run Code Online (Sandbox Code Playgroud)

打电话时不带* FROM

SELECT myfunc_single();
Run Code Online (Sandbox Code Playgroud)

不适用于 SRF(设置返回函数),仅返回整个记录的字符串表示形式(类型record)。很少有用。
要从单个匿名记录中获取各个列,您需要再次提供列定义列表:

SELECT * FROM myfunc_single() AS (id int, txt unknown); -- note "unknown" type
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

该函数返回表的所有列。这是简短而简单的,只要您的表不包含大量列或巨大的列,性能就不会受到影响。

选择通话中的各个列:

SELECT id, txt FROM myfunc_tbl();
SELECT id, the_date FROM myfunc_tbl();
Run Code Online (Sandbox Code Playgroud)

-> SQLfiddle演示了所有内容。

3)先进的解决方案

这个答案已经够长了。这个密切相关的答案已经说明了一切:
重构 PL/pgSQL 函数以返回各种 SELECT 查询的输出

特别看最后一章:各种完整的表类型