После глубокого глубокого исследования я создал свою собственную версию, которая обрабатывает все таблицы и получает максимальный уровень таблицы в иерархии (она считывает все схемы с учетом таблиц без родительских и дочерних отношений, которые будут на уровне 1 наряду с корневыми). Если у вас есть доступ, используйте таблицы dba_ вместо всех_.
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 (
/*----------------------------------------------------------------------*/
/* Retrieve all tables. Set them as the Child column, and set their */
/* Parent Column to NULL. This is the root list (first iteration) */
/*----------------------------------------------------------------------*/
SELECT NULL parent_table
, a.owner || '.' || a.table_name child_table
FROM all_tables a
UNION
/*----------------------------------------------------------------------*/
/* List of all possible Parent-Child relations. This table is used as */
/* a link list, to link the current iteration with the next one, from */
/* root to last child (last child is what we are interested to find). */
/*----------------------------------------------------------------------*/
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
/*----------------------------------------------------------------------*/
/* NOCYCLE prevents infinite loops (i.e. self referencing table constr) */
/*----------------------------------------------------------------------*/
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:
При поиске бесконечных циклов возникает «разновидность» этого запроса.
Если у нас есть это дерево:
b --> c --> d
b <-- c
назначит 2 уровня для c: b --> c
и lvl 2 до b как: c --> b
для d, он обнаружит b --> c --> d
поэтому он назначит 3
лвл
Итак, как вы можете видеть, проблема в цикле, значения снаружи всегда будут иметь максимальный правильный уровень lvl