返回类型的简单方法是SETOF表加上其他字段?

时间:2013-07-23 21:34:29

标签: postgresql plpgsql postgresql-9.2 compositetype

我正在编写一个PL / pgSQL存储过程,它将返回一组记录;每条记录都包含现有表的所有字段(称之为零售商,它有两个字段:retailer_key和retailer_name)。当然,这有效:

CREATE FUNCTION proc_Find_retailers
 (IN p_Store_key INT)
   RETURNS SETOF Retailer
   AS $$ ...`

现在我想更新sp,以便它为每个返回记录的'end'返回另外两个字段。我可以做一些事情,比如:

CREATE FUNCTION proc_Find_store
 (IN p_Store_key INT)
   RETURNS TABLE (
      retailer_key int,
      retailer_name varchar(50),
      addl_field_1 int,
      addl_field_2 double precision)
   AS $$ ...

在现实世界中,我的零售商表有50个字段(在我的示例中不是两个),因此在RETURNS TABLE子句中枚举所有这些字段是单调乏味的。有没有这方面的捷径,所以我可能会说些什么(我知道我在这里制作的东西在语法上是非法的,但我这样做是为了给你一些我正在寻找的东西):< / p>

CREATE FUNCTION proc_Find_store
 (IN p_Store_key INT)
   RETURNS (SETOF Store,
      addl_field_1 int,
      addl_field_2 double precision)
   AS $$ ...

1 个答案:

答案 0 :(得分:4)

可以将整行作为复合类型返回并添加更多:

CREATE OR REPLACE FUNCTION f_rowplus()
  RETURNS TABLE (rec demo, add_int int, add_txt text) AS
$func$
SELECT d, 5, 'baz'::text FROM demo d;
$func$  LANGUAGE sql;

但是,当你使用简单的电话时:

SELECT * FROM f_rowplus();

您从表demo获取行作为单独的复合类型。你必须打电话:

SELECT (rec).*,  add_int, add_txt FROM f_rowplus();

获取所有个人列。需要括号。

除此之外:这仍然只评估函数一次 - 而像这样的直接调用将为返回类型中的每一列评估一次:

SELECT (f_rowplus()).*;

详细说明:

Postgres在这里有点不一致。如果使用

创建函数
CREATE OR REPLACE FUNCTION f_row2()
  RETURNS TABLE (rec demo) AS
...

然后将其静默转换为单个列(已分解)。未链接到原始复合类型。您根本无法引用声明的输出列rec,因为它已被分解类型的列替换。此调用将导致错误消息:

SELECT rec FROM f_row2();

同样在这里:

CREATE OR REPLACE FUNCTION f_row3(OUT rec demo)
  RETURNS SETOF demo AS
...

但是,只要您添加任何更多OUT列,复合类型就会保留为已声明(未分解),您可以:

SELECT rec FROM f_rowplus();

第一个功能。

我创建了SQL Fiddle来演示变体。


<强> 除了
当使用函数返回FROM列表中的多个列(作为表函数)并在SELECT列表中进行分解时,如下所示:

SELECT (rec).* FROM f_rowplus();

...该功能仅在一次评估 - 而调用SELECT列表中直接分解如下:

SELECT (f_rowplus()).*;  -- also: different result

...将为返回类型中的每个列评估一次。详细说明: