Oracle
 sql >> Base de données >  >> RDS >> Oracle

La requête récursive pour les dépendances de table n'est pas récurrente autant que je le voudrais

Vous voulez quelque chose comme ça :

select t.table_name, level,lpad(' ', 2 * (level - 1))||t.table_name 
from user_tables t
join user_constraints c1 
    on (t.table_name = c1.table_name 
    and c1.constraint_type in ('U', 'P'))
left join user_constraints c2 
    on (t.table_name = c2.table_name 
    and c2.constraint_type='R')
start with t.table_name = 'ROOT_TAB'
connect by prior c1.constraint_name = c2.r_constraint_name

Le problème avec la requête d'origine est que uc.constraint_name pour la table enfant est le nom de la clé étrangère. C'est bien pour connecter le premier enfant à la table racine, mais ce n'est pas ce dont vous avez besoin pour connecter les enfants du deuxième niveau au premier. C'est pourquoi vous devez joindre deux fois les contraintes :une fois pour obtenir la clé primaire de la table, une fois pour obtenir les clés étrangères.

Soit dit en passant, si vous allez interroger les vues all_* plutôt que les vues user_*, vous souhaitez généralement les joindre sur table_name AND owner, pas seulement table_name. Si plusieurs schémas ont des tables portant le même nom, joindre uniquement table_name donnera des résultats incorrects.