select parent, child, level from (
select parent_table.table_name parent, child_table.table_name child
from user_tables parent_table,
user_constraints parent_constraint,
user_constraints child_constraint,
user_tables child_table
where parent_table.table_name = parent_constraint.table_name
and parent_constraint.constraint_type IN( 'P', 'U' )
and child_constraint.r_constraint_name = parent_constraint.constraint_name
and child_constraint.constraint_type = 'R'
and child_table.table_name = child_constraint.table_name
and child_table.table_name != parent_table.table_name
)
start with parent = 'DEPT'
connect by prior child = parent
dovrebbe funzionare (sostituire il nome della tabella, ovviamente) supponendo che tutto sia nello stesso schema. Utilizzare le versioni DBA_ delle tabelle e delle condizioni del dizionario dati per le colonne OWNER e R_OWNER se è necessario gestire le dipendenze tra schemi. A ulteriore riflessione, questo non tiene conto nemmeno dei vincoli autoreferenziali (cioè un vincolo sulla tabella EMP che la colonna MGR fa riferimento alla colonna EMPNO), quindi dovresti modificare il codice per gestire quel caso se hai bisogno di trattare con vincoli autoreferenziali.
A scopo di test, ho aggiunto alcune nuove tabelle allo schema SCOTT che fanno riferimento anche alla tabella DEPT (inclusa una dipendenza nipote)
SQL> create table dept_child2 (
2 deptno number references dept( deptno )
3 );
Table created.
SQL> create table dept_child3 (
2 dept_child3_no number primary key,
3 deptno number references dept( deptno )
4 );
Table created.
SQL> create table dept_grandchild (
2 dept_child3_no number references dept_child3( dept_child3_no )
3 );
Table created.
e verificato che la query restituisse l'output previsto
SQL> ed
Wrote file afiedt.buf
1 select parent, child, level from (
2 select parent_table.table_name parent, child_table.table_name child
3 from user_tables parent_table,
4 user_constraints parent_constraint,
5 user_constraints child_constraint,
6 user_tables child_table
7 where parent_table.table_name = parent_constraint.table_name
8 and parent_constraint.constraint_type IN( 'P', 'U' )
9 and child_constraint.r_constraint_name = parent_constraint.constraint_name
10 and child_constraint.constraint_type = 'R'
11 and child_table.table_name = child_constraint.table_name
12 and child_table.table_name != parent_table.table_name
13 )
14 start with parent = 'DEPT'
15* connect by prior child = parent
SQL> /
PARENT CHILD LEVEL
------------------------------ ------------------------------ ----------
DEPT DEPT_CHILD3 1
DEPT_CHILD3 DEPT_GRANDCHILD 2
DEPT DEPT_CHILD2 1
DEPT EMP 1