我正在编写一个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 $$ ...
答案 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
...将为返回类型中的每个列评估一次。详细说明: