【问题标题】:How to call table function from another function in PostgreSQL?如何从 PostgreSQL 中的另一个函数调用表函数?
【发布时间】:2018-01-09 07:55:15
【问题描述】:

我是 PostgreSQL 新手。

我有一个函数

CREATE OR REPLACE FUNCTION func1 ( a_person_id integer) RETURNS TABLE (granted_group_id varchar(10)) AS $body$

          WITH v_granted_group_list AS (
          SELECT DISTINCT a.group_id 
                FROM a_table a
               )
        SELECT v.group_id FROM v_granted_group_list v;

$body$
LANGUAGE sql;

我想在其他函数func2中使用这个的输出。

我尝试按照以下代码执行此操作,但出现错误。

我们可以用什么来代替v_access_groups 数组?

CREATE OR REPLACE FUNCTION func2 ( a_person_id IN integer,mhrc_emp_no IN varchar(50)) 
 RETURNS TABLE (granted_group_id varchar(10)) AS $body$
DECLARE

   v_access_groups varchar[];
BEGIN

      v_access_groups := func1(a_person_id);
      ---- this gives error
      ---ERROR:  malformed array literal: "LCCHG"
      ----DETAIL:  Array value must start with "{" or dimension information.
      --------CONTEXT:  PL/pgSQL function func2(integer,character varying) line 14 at SQL statement

      -- what can we you in place of v_access_groups array
    RETURN v_access_groups;
  END;
$body$
LANGUAGE PLPGSQL;

我想在选择查询的另一个函数中使用func2 的结果

CREATE OR REPLACE FUNCTION func3 ( a_blurb_id integer, a_person_id integer,mhrc_emp_no varchar(20)) RETURNS boolean AS $body$
DECLARE

     v_acc_count         numeric;
     v_accessAllowed     boolean:=FALSE;
BEGIN
    SELECT COUNT(*) INTO v_acc_count
    FROM table1 agfa
    where  agfa.group_id IN (
        SELECT TO_CHAR(column_value) AS group_id
        FROM TABLE(func2(a_person_id,mhrc_emp_no))
    );
    RETURN TRUE;
  END;
$body$
LANGUAGE PLPGSQL;

如何在 PostgreSQL 中实现这一点?

【问题讨论】:

  • 使用横向连接
  • @mursion 我是 postgres 的新手。怎样才能做到这一点?

标签: database postgresql plpgsql postgresql-9.4


【解决方案1】:

您可以像往常一样引用函数返回表。例如,您的函数func1 返回一列varchar(10)。没有你的结构,我将使用generate_series。所以lateral join @murison 正在潜伏着就像:

t=# select pg_class.oid 
from pg_class
join lateral generate_series(11700,11711,1) g on pg_class.oid = g 
;
  oid  
-------
 11701
 11704
 11707
 11711
(4 rows)

这里我得到 11700 和 11711 之间的 oid,因为我的 generate_series 将返回值:11700、11701、11702 等等,直到 11711...

您想要使用IN 运算符的解决方案也很简单:

t=# select oid from pg_class
where oid IN (select generate_series(11700,11711,1));
  oid  
-------
 11701
 11704
 11707
 11711
(4 rows)

所以您不需要将func1 的结果除以func2 中的数组。

【讨论】:

    【解决方案2】:

    您可以像使用表一样在查询中使用集合返回函数(表函数)。

    因此,要将结果分配给名为 v_access_groupstext[],您可以执行以下操作:

    SELECT array_agg(granted_group_id) INTO v_access_groups FROM func1(a_person_id);
    

    但是您的func2 应该只包含:

    RETURN QUERY SELECT * FROM func1(a_person_id);
    

    如果您省略 TABLE(...) 表达式,您的 func3 应该可以工作 - 只需将函数视为表,无需额外语法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-03
      • 2014-04-19
      • 1970-01-01
      相关资源
      最近更新 更多