如何从PostgreSQL中的另一个函数调用表函数?

问题描述:

我是PostgreSQL的新手。如何从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中实现这一目标?

+0

使用横向连接 – murison

+0

@mursion我是新来的postgres。怎么能做到这一点? –

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

所以分配结果的text[]名为v_access_groups,你可以进行如下操作:

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

但你func2应该只包含:

RETURN QUERY SELECT * FROM func1(a_person_id); 

如果省略你func3应该工作TABLE(...)表达式–只是将函数像表一样对待,没有额外的语法。

你可以像往常一样引用函数返回表。例如,你的功能func1返回一列varchar(10)。没有你的结构我会用generate_series。所以lateral join @murison是latking大约是水木清华这样的:

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,因为我generate_series将返回值之间的OID:11700,11701,11702,并以此类推,直到11711 ...

IN运营商所需的解决方案是非常简单和:所以你除以func1结果到阵列中的func2只是不需要

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