After deep in-depth research, I made my own version, which processes all tables and returns the level of the maximum table in the hierarchy (it reads all the schemes, taking into account tables without parent-child relationships, which will be at level 1 along with the root ones). If you have access, use the dba_ tables instead of all_ units.
WITH hier AS ( SELECT child_table owner_table_name , LEVEL lvl , LPAD (' ', 4 * (LEVEL - 1)) || child_table indented_child_table , sys_connect_by_path( child_table, '|' ) tree FROM ( SELECT NULL parent_table , a.owner || '.' || a.table_name child_table FROM all_tables a UNION SELECT p.owner || '.' || p.table_name parent_table , c.owner || '.' || c.table_name child_table FROM all_constraints p, all_constraints c WHERE p.owner || '.' || p.constraint_name = c.r_owner || '.' || c.r_constraint_name AND (p.constraint_type = 'P' OR p.constraint_type = 'U') AND c.constraint_type = 'R' ) START WITH parent_table IS NULL CONNECT BY NOCYCLE PRIOR child_table = parent_table ) SELECT * FROM hier WHERE (owner_table_name, lvl) IN ( SELECT owner_table_name , MAX(lvl) FROM hier GROUP BY owner_table_name );
Edit: There is a βkindaβ problem with this query when searching for infinite loops.
If we have this tree:
b --> c --> d b <-- c
it will assign lvl 2 to c as follows: b --> c and lvl 2 - b as: c --> b
for d, it will detect b --> c --> d so it will assign lvl 3
So, as you can see, the problem is inside the loop, the values ββfrom the outside will always have the maximum correct lvl
source share