Postgres 递归构建具有数组值的 CTE



我有一个表示函数名称的字符串数组。我需要遍历它们才能调用每个函数。它们根据与函数中其他表匹配的条件来区分行。我需要累积行进行单独的查询,并且认为递归 CTE 将是要走的路。但是,我无法增加引用数组索引的数字。有什么建议吗?此外,如果这只是一个糟糕的方法,任何提示都会很好:D

CREATE OR REPLACE FUNCTION fn_name(target_table TEXT, identifier INT) returns setof table_name as
$$
DECLARE
function_names text[];
BEGIN
function_names := '{fn1, fn2, fn3}';
WITH RECURSIVE non_matches(n) as (
SELECT * FROM non_matching_records($1, $2, function_names[1])
UNION
SELECT * FROM non_match_records($1, $2, function_names[n+1] 
WHERE n < ARRAY_LENGTH(function_names, 1) + 1
)
SELECT * FROM non_matches;
END
$$ LANGUAGE plpgsql;

编辑:删除了对同一表返回的引用。我忘了这就是为什么我要接受表参数,以便它可以返回 void。我需要从每个函数返回的记录集合,以便能够对它们运行另一个查询。

更新:

这是我使用递归查询 atm 的地方:

WITH RECURSIVE non_matches AS (
SELECT *, 1 AS depth FROM non_matching_records($1, $2, function_names[1])
UNION
SELECT c.*, nm.depth + 1 AS depth FROM non_matching_records($1, $2, function_names[nm.depth]) c, non_matches nm
)
SELECT * FROM non_matches;

我从此更新收到的错误是没有名为"如果我不包含 CTE 名称depth"的列。如果我使用它,则没有 CTE 条目。不太确定如何在括号中访问它以访问数组。

non_matching_records是一个查找不匹配记录的函数。

我只是遍历数组并使用RETURN QUERY EXECUTE调用每个函数。

CREATE OR REPLACE FUNCTION fn_name(target_table regclass, identifier INT) returns setof table_name AS
$$
DECLARE 
function_names regproc[] := '{fn1, fn2, fn3}';
fn regproc;
BEGIN
FOREACH fn IN ARRAY function_names
LOOP
RETURN QUERY EXECUTE format('SELECT * FROM %s(%s, %L)', fn, $1, $2);
END LOOP;
RETURN;
END;
$$ LANGUAGE PLPGSQL;

我在这里使用了 regclass 和 regproc 来帮助对表和函数进行模式限定,但只要您注意如何调用它们,您就可以将它们改回文本。

昨晚终于得到了它。事实证明,一旦我添加了depth列,我最初就从错误的"表">中进行选择。我切换了表的顺序,首先使用 cte,然后与返回记录的函数连接。这使我可以访问深度列,并允许我增加索引

WITH RECURSIVE non_matches AS (
SELECT c.*, 1 AS depth FROM non_matching_records($1, $2, function_names[1]) c
UNION
SELECT c.*, nm.depth + 1 as depth 
FROM non_matches nm, non_matching_records($1, $2, function_names[nm.depth]) c
WHERE nm.depth < array_length(match_rules, 1) + 1
)

最新更新