Frage

Ich versuche, eine Abhängigkeitsgraphen von Tabellen zwischen ihnen basierend auf den Fremdschlüssel zu bauen. Dieser Graph muss mit einem beliebigen Tabellennamen als Wurzel starten. Ich kann, da ein Tabellenname die Tabellen nachschlagen, die sie mit Hilfe der all_constraints Referenzansicht, dann die Tabellen nachschlagen, die darauf verweisen, und so weiter, aber das wäre ineffizient schrecklich sein. Ich schrieb eine rekursive Abfrage, die dies für alle Tabellen der Fall ist, aber wenn ich hinzufügen:

START WITH Table_Name=:tablename

Es wird nicht die gesamte Struktur zurück.

War es hilfreich?

Lösung

    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

funktionieren soll (die Tabellennamen ersetzen, natürlich) davon aus, dass alles in demselben Schema ist. Verwenden Sie die DBA_ Versionen der Data Dictionary-Tabellen und Bedingungen für den Eigentümer und R_OWNER Spalten, wenn Sie Quer Schema Abhängigkeiten behandeln müssen. Auf weitere Überlegungen, diese nicht berücksichtigt selbstbezogenen Einschränkungen (dh eine Einschränkung für die Tabelle EMP, dass die Spalte MGR die ANGNR Spalte verweist) entweder, so dass Sie den Code ändern müssen, würde den Fall zu behandeln, wenn Sie befassen müssen mit selbstbezogenen Einschränkungen.

Zu Testzwecken haben ich ein paar neue Tabellen zum SCOTT-Schema, das auch die DEPT Tabelle verweisen (einschließlich einem Enkelkind Abhängigkeit)

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.

und überprüft, dass die Abfrage die erwartete Ausgabe zurückgegeben

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

Andere Tipps

einfachste Weg, dies zu tun, ist es, all FK Informationen in eine einfachen zu kopieren, 2-Säule (Eltern, Kinder) Tabelle, und verwenden Sie dann den folgenden Algorithmus:

while (rows left in that table)
  list = rows where table name exists in child but not in parent
  print list
  remove list from rows

Das ist alles. Grundsätzlich Sie Erstdruck und entfernen Sie alle Knoten, die nicht auf irgendetwas hängen. Nachdem das getan wird, werden einige andere Knoten erhalten kostenlos und Sie können Vorgang wiederholen.

P. S. Stellen Sie sicher, dass Sie legen nicht sich selbst verweisende Tabellen in der ersten Liste (child = parent)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top