PL/pgSQL - 从 FUNCTION 返回单个记录
Posted
技术标签:
【中文标题】PL/pgSQL - 从 FUNCTION 返回单个记录【英文标题】:PL/pgSQL - return single record from FUNCTION 【发布时间】:2017-01-09 12:23:14 【问题描述】:我正在使用 PL/pgSQL 创建一个 SP:
CREATE OR REPLACE FUNCTION get_performance_achieve (p_month INT,p_year INT, p_uid INT)
RETURNS TABLE (
field1 INT,
field2 INT
)
AS $datarows$
DECLARE var_r record;
BEGIN
field1 :=0;
field2 :=0;
FOR var_r IN(select COUNT(id) as counter from "TABLE_A"
)
LOOP
field1 := (var_r.counter) ;
RETURN NEXT;
END LOOP;
FOR var_r IN(select COUNT(id) as counter from "TABLE_B"
)
LOOP
field2 := (var_r.counter) ;
RETURN NEXT;
END LOOP;
END;
$datarows$
LANGUAGE 'plpgsql';
当我执行 SP 时,它会返回 2 条记录:
-
field1 , 0
字段1,字段2
我怎样才能只用 field1, field2
返回一条记录【问题讨论】:
【参考方案1】:如果您想返回一条记录,我看不出您使用 returns table
的原因。一个简单的returns record
就可以做到这一点:返回一条记录:
CREATE OR REPLACE FUNCTION get_performance_achieve (p_month INT,p_year INT, p_uid INT)
RETURNS record --<< here
AS $datarows$
DECLARE
l_count1 bigint;
l_count2 bigint;
BEGIN
select COUNT(id) into l_count1 from "TABLE_A";
select COUNT(id) into l_count2 from "TABLE_B";
RETURN (l_count1, l_count2);
END;
$datarows$
LANGUAGE plpgsql;
要运行它,请使用例如:
select get_performance_achieve(1,2017,42);
然而,上面创建了一个 匿名 记录,其中字段没有名称。
如果需要,请声明两个 OUT
参数:
CREATE OR REPLACE FUNCTION get_performance_achieve (p_month INT,p_year INT, p_uid INT, field1 out integer, field2 out integer)
AS $datarows$
BEGIN
select COUNT(id) into field1 from "TABLE_A";
select COUNT(id) into field2 from "TABLE_B";
RETURN (l_count1, l_count2);
END;
$datarows$
LANGUAGE plpgsql;
你也这么称呼它:
select get_performance_achieve(1,2017,42);
它会返回例如(1,2)
如果要将记录的每个字段作为结果的一列查看,则需要使用:
select (get_performance_achieve(1,2017,42)).*;
对于第一个示例中所示的匿名记录,上述情况是不可能的。
【讨论】:
这将是我正在寻找的答案【参考方案2】:在这种情况下循环是多余的,使用简单的赋值:
CREATE OR REPLACE FUNCTION get_performance_achieve (p_month INT,p_year INT, p_uid INT)
RETURNS TABLE (
field1 INT,
field2 INT
)
AS $datarows$
BEGIN
field1 := (select COUNT(id) as counter from "TABLE_A");
field2 := (select COUNT(id) as counter from "TABLE_B");
RETURN NEXT;
END;
$datarows$
LANGUAGE plpgsql;
请注意,尽管该函数返回单行,但它仍然是一个集合返回函数。因此它应该用在FROM
子句中:
SELECT * FROM get_performance_achieve(1,2017,42);
另一个答案中描述的带有OUT
参数的变体严格返回一行,看起来更简单。可以从SELECT
列表中调用这样的函数。但是,我不建议以这种方式使用它:
SELECT (get_performance_achieve(1,2017,42)).*;
因为函数被调用的次数与结果中的列数一样多(在本例中为两次)。
【讨论】:
上面的代码不能解决“从FUNCTION返回单条记录”的问题。尝试执行此代码:sql CREATE OR REPLACE FUNCTION get_performance_achieve () RETURNS TABLE ( field1 INT, field2 INT ) AS $datarows$ BEGIN field1 := (select 1); field2 := (select 2); RETURN NEXT; END; $datarows$ LANGUAGE 'plpgsql'; select (get_performance_achieve()).field1 is not null and true;
结果:[42804] ERROR: argument of AND must not return a set
@Rinat - 我已经添加了一些解释。以上是关于PL/pgSQL - 从 FUNCTION 返回单个记录的主要内容,如果未能解决你的问题,请参考以下文章
使用 PL/pgSQL 在 PostgreSQL 中将多个字段作为记录返回