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;

db<>fiddle