从 PL/pgSQL 中的函数调用 table 函数 - 这可能吗?

Call table functions from function in PL/pgSQL - is that possible?

我有两个类似的函数,结果相同 table,我想创建一个函数来选择要执行的函数。

我的函数是从如下代码创建的 - function_afunction_b:

CREATE OR REPLACE FUNCTION function_a(sys_id integer)
    RETURNS TABLE (
        col_1 text,
        col_2 text,
        col_3 text) AS $$
        (...)
        END; $$
    LANGUAGE 'plpgsql';

我想得到这样的东西(这段代码不起作用,但我认为它表达了我的意图):

CREATE OR REPLACE FUNCTION choose_function(system text, sys_id integer)
    RETURNS TABLE (
        col_1 text,
        col_2 text,
        col_3 text) AS $$
        BEGIN   
            IF system = 'A' THEN RETURN
                (select * from function_a(sys_id));
            ELSEIF system = 'B' THEN RETURN 
                (select * from function_b(sys_id));
            END IF;
        END; $$
    LANGUAGE 'plpgsql';

我收到一个错误: ERROR: RETURN cannot have a parameter in function returning set 并提示: HINT: Use RETURN NEXT or RETURN QUERY. 但是使用 RETURN QUERY 导致我收到空的 table 或者更确切地说 headers 并且使用 RETURN NEXT 也给我一个错误:ERROR: RETURN NEXT cannot have a parameter in function with OUT parameters.

是否可以满足我的需求?

没有问题是可以的。每个函数都有自己的输出栈——顶层函数的输出栈是可见的结果。没有一个全局输出堆栈。所以你不能调用 table 函数而不将它们的结果存储在调用者输出堆栈中。这可以通过命令 RETURN QUERY:

来完成
CREATE OR REPLACE FUNCTION f_a(a int)
RETURNS TABLE (b int, c int) AS
$$
  SELECT i, i+1 FROM generate_series(1,a)
$$ LANGUAGE sql;

CREATE OR REPLACE FUNCTION f_b(a int)
RETURNS TABLE (b int, c int) AS
$$
  SELECT i, i*10 FROM generate_series(1,a)
$$ LANGUAGE sql;

CREATE OR REPLACE FUNCTION f2(par1 text, a int)
RETURNS TABLE (b int, c int) AS 
$$
BEGIN
  IF par1 = 'A' THEN
    RETURN QUERY SELECT * FROM f_a(a);
  ELSE
    RETURN QUERY SELECT * FROM f_b(a);
  END IF;
  RETURN;
END;
$$ LANGUAGE plpgsql;

CREATE TABLE test(par1 text, a int);
INSERT INTO test('a', 10);
INSERT INTO test('b', 3);

SELECT f2.* FROM test, LATERAL f2(par1, a);