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 函数在 pgAdmin 之外无法正确运行

如何在 PL/pgSQL 中按行类型返回表

使用 PL/pgSQL 在 PostgreSQL 中将多个字段作为记录返回

PL/pgSQL:触发函数返回不正确的数据

如何在 pl/pgsql 中创建返回 refcursor 和 totalRow 的函数/过程?

PL/pgSQL 函数会自行自动提交吗?