具有数组值的 CTE 的 Postgres 递归构建
Postgres recursive building of CTE with array values
我有一个表示函数名称的字符串数组。我需要遍历它们才能调用每个函数。它们根据与函数中其他 table 匹配的条件来区分行。我需要单独查询的累积行,并且认为递归 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(, , function_names[1])
UNION
SELECT * FROM non_match_records(, , function_names[n+1]
WHERE n < ARRAY_LENGTH(function_names, 1) + 1
)
SELECT * FROM non_matches;
END
$$ LANGUAGE plpgsql;
编辑: 删除了对相同 table return 的引用。我忘了这就是我接受 table 参数的原因,这样它就可以 return 无效。我需要从每个函数 returned 收集记录,以便能够 运行 对它们进行另一个查询。
更新:
这里是我的递归查询 atm:
WITH RECURSIVE non_matches AS (
SELECT *, 1 AS depth FROM non_matching_records(, , function_names[1])
UNION
SELECT c.*, nm.depth + 1 AS depth FROM non_matching_records(, , function_names[nm.depth]) c, non_matches nm
)
SELECT * FROM non_matches;
我从这次更新中收到的错误是没有名为 depth
的列,如果我不包括 CTE 名称。如果我使用它,则没有 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, , );
END LOOP;
RETURN;
END;
$$ LANGUAGE PLPGSQL;
我在这里使用了 regclass 和 regproc 来帮助对表和函数进行模式限定,但是您可以将它们改回文本,只要您注意它们的调用方式即可。
昨晚终于搞定了。事实证明,一旦我添加了 depth
列,我最初从 中选择了 错误的 'table'。我切换了表的顺序,首先是 cte,然后 然后 与 returns 记录的函数连接。这使我可以访问深度列并允许我增加索引
WITH RECURSIVE non_matches AS (
SELECT c.*, 1 AS depth FROM non_matching_records(, , function_names[1]) c
UNION
SELECT c.*, nm.depth + 1 as depth
FROM non_matches nm, non_matching_records(, , function_names[nm.depth]) c
WHERE nm.depth < array_length(match_rules, 1) + 1
)
我有一个表示函数名称的字符串数组。我需要遍历它们才能调用每个函数。它们根据与函数中其他 table 匹配的条件来区分行。我需要单独查询的累积行,并且认为递归 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(, , function_names[1])
UNION
SELECT * FROM non_match_records(, , function_names[n+1]
WHERE n < ARRAY_LENGTH(function_names, 1) + 1
)
SELECT * FROM non_matches;
END
$$ LANGUAGE plpgsql;
编辑: 删除了对相同 table return 的引用。我忘了这就是我接受 table 参数的原因,这样它就可以 return 无效。我需要从每个函数 returned 收集记录,以便能够 运行 对它们进行另一个查询。
更新:
这里是我的递归查询 atm:
WITH RECURSIVE non_matches AS (
SELECT *, 1 AS depth FROM non_matching_records(, , function_names[1])
UNION
SELECT c.*, nm.depth + 1 AS depth FROM non_matching_records(, , function_names[nm.depth]) c, non_matches nm
)
SELECT * FROM non_matches;
我从这次更新中收到的错误是没有名为 depth
的列,如果我不包括 CTE 名称。如果我使用它,则没有 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, , );
END LOOP;
RETURN;
END;
$$ LANGUAGE PLPGSQL;
我在这里使用了 regclass 和 regproc 来帮助对表和函数进行模式限定,但是您可以将它们改回文本,只要您注意它们的调用方式即可。
昨晚终于搞定了。事实证明,一旦我添加了 depth
列,我最初从 中选择了 错误的 'table'。我切换了表的顺序,首先是 cte,然后 然后 与 returns 记录的函数连接。这使我可以访问深度列并允许我增加索引
WITH RECURSIVE non_matches AS (
SELECT c.*, 1 AS depth FROM non_matching_records(, , function_names[1]) c
UNION
SELECT c.*, nm.depth + 1 as depth
FROM non_matches nm, non_matching_records(, , function_names[nm.depth]) c
WHERE nm.depth < array_length(match_rules, 1) + 1
)