with fk_list as (
select parent_table.table_name parent,
parent_cons.constraint_name as pk_constraint,
child_table.table_name child,
child_cons.constraint_name as fk_constraint
from user_tables parent_table
join user_constraints parent_cons on parent_table.table_name = parent_cons.table_name and parent_cons.constraint_type IN ('P', 'U')
join user_constraints child_cons on child_cons.r_constraint_name = parent_cons.constraint_name and child_cons.constraint_type = 'R'
join user_tables child_table on child_table.table_name = child_cons.table_name and child_table.table_name <> parent_table.table_name
)
select level,
fl.child,
(select listagg(fk.column_name,',') within group (order by fk.position) from user_cons_columns fk where fk.constraint_name = fl.fk_constraint) as fk_columns,
fl.parent,
(select listagg(pk.column_name,',') within group (order by pk.position) from user_cons_columns pk where pk.constraint_name = fl.pk_constraint) as pk_columns
from fk_list fl
where fl.child <> fl.parent
start with fl.parent = 'root table'
connect by prior fl.child = fl.parent
order by level;
我通常使用这个语句。
它不是最有效的,但它确实对我有用。
请注意,由于使用,它需要 11.2
listagg()