MySQl 8.0.23 中如何递归查询引用约束?
How to Recursively Query Referential Constraints in MySQl 8.0.23?
我正在尝试在 MySql 8.0.23 中编写一个递归查询到 return 指向指定 table 的直接和间接外键关系。从 table T1 开始,结果集应显示 T2 和 T3 中的每一个都指向 T1(通过已建立的约束),T4 指向 T2,T5 和 T6 指向 T3,等等
以下是我正在使用的查询,它挂起/似乎永远失控:
WITH RECURSIVE CTE AS (
SELECT REFERENTIAL_CONSTRAINTS.REFERENCED_TABLE_NAME, REFERENTIAL_CONSTRAINTS.TABLE_NAME, 0 AS DEPTH
FROM information_schema.REFERENTIAL_CONSTRAINTS
WHERE REFERENTIAL_CONSTRAINTS.CONSTRAINT_SCHEMA = 'MY_SCHEMA' AND REFERENTIAL_CONSTRAINTS.REFERENCED_TABLE_NAME = 'TABLE_A'
UNION ALL
SELECT REFERENTIAL_CONSTRAINTS.REFERENCED_TABLE_NAME, REFERENTIAL_CONSTRAINTS.TABLE_NAME, CTE.DEPTH + 1
FROM CTE
INNER JOIN information_schema.REFERENTIAL_CONSTRAINTS ON CTE.TABLE_NAME = REFERENTIAL_CONSTRAINTS.REFERENCED_TABLE_NAME
)
SELECT *
FROM CTE;
对于我做错了什么的任何建议,我将不胜感激。谢谢
也许您有一个引用自身的 table 或一个更广泛的循环,您必须跟踪您已经检查过的 table,如下面的 table_list 所示:
WITH RECURSIVE CTE AS
(
SELECT
concat('`', rc.REFERENCED_TABLE_NAME, '`', '<-', '`', rc.TABLE_NAME, '`') as table_list,
rc.REFERENCED_TABLE_NAME,
rc.TABLE_NAME,
0 AS DEPTH
FROM information_schema.REFERENTIAL_CONSTRAINTS rc
WHERE rc.REFERENCED_TABLE_NAME = 'TABLE_A'
UNION ALL
SELECT
concat(table_list, '<-', '`', rc.TABLE_NAME, '`') as table_list,
rc.REFERENCED_TABLE_NAME,
rc.TABLE_NAME,
CTE.DEPTH + 1
FROM CTE
INNER JOIN information_schema.REFERENTIAL_CONSTRAINTS rc ON CTE.TABLE_NAME = rc.REFERENCED_TABLE_NAME
WHERE
(rc.table_name != rc.REFERENCED_TABLE_NAME and table_list not like concat('`%<-', '`', rc.TABLE_NAME, '`%'))
or (rc.table_name = rc.REFERENCED_TABLE_NAME and table_list not like concat('%`', rc.TABLE_NAME, '`', '<-', '`', rc.TABLE_NAME, '`%'))
)
SELECT
*
FROM CTE;
我正在尝试在 MySql 8.0.23 中编写一个递归查询到 return 指向指定 table 的直接和间接外键关系。从 table T1 开始,结果集应显示 T2 和 T3 中的每一个都指向 T1(通过已建立的约束),T4 指向 T2,T5 和 T6 指向 T3,等等
以下是我正在使用的查询,它挂起/似乎永远失控:
WITH RECURSIVE CTE AS (
SELECT REFERENTIAL_CONSTRAINTS.REFERENCED_TABLE_NAME, REFERENTIAL_CONSTRAINTS.TABLE_NAME, 0 AS DEPTH
FROM information_schema.REFERENTIAL_CONSTRAINTS
WHERE REFERENTIAL_CONSTRAINTS.CONSTRAINT_SCHEMA = 'MY_SCHEMA' AND REFERENTIAL_CONSTRAINTS.REFERENCED_TABLE_NAME = 'TABLE_A'
UNION ALL
SELECT REFERENTIAL_CONSTRAINTS.REFERENCED_TABLE_NAME, REFERENTIAL_CONSTRAINTS.TABLE_NAME, CTE.DEPTH + 1
FROM CTE
INNER JOIN information_schema.REFERENTIAL_CONSTRAINTS ON CTE.TABLE_NAME = REFERENTIAL_CONSTRAINTS.REFERENCED_TABLE_NAME
)
SELECT *
FROM CTE;
对于我做错了什么的任何建议,我将不胜感激。谢谢
也许您有一个引用自身的 table 或一个更广泛的循环,您必须跟踪您已经检查过的 table,如下面的 table_list 所示:
WITH RECURSIVE CTE AS
(
SELECT
concat('`', rc.REFERENCED_TABLE_NAME, '`', '<-', '`', rc.TABLE_NAME, '`') as table_list,
rc.REFERENCED_TABLE_NAME,
rc.TABLE_NAME,
0 AS DEPTH
FROM information_schema.REFERENTIAL_CONSTRAINTS rc
WHERE rc.REFERENCED_TABLE_NAME = 'TABLE_A'
UNION ALL
SELECT
concat(table_list, '<-', '`', rc.TABLE_NAME, '`') as table_list,
rc.REFERENCED_TABLE_NAME,
rc.TABLE_NAME,
CTE.DEPTH + 1
FROM CTE
INNER JOIN information_schema.REFERENTIAL_CONSTRAINTS rc ON CTE.TABLE_NAME = rc.REFERENCED_TABLE_NAME
WHERE
(rc.table_name != rc.REFERENCED_TABLE_NAME and table_list not like concat('`%<-', '`', rc.TABLE_NAME, '`%'))
or (rc.table_name = rc.REFERENCED_TABLE_NAME and table_list not like concat('%`', rc.TABLE_NAME, '`', '<-', '`', rc.TABLE_NAME, '`%'))
)
SELECT
*
FROM CTE;