Building a Table Dependency Graph With A Recursive Query

前端 未结 2 1565
无人及你
无人及你 2020-12-30 16:06

I am trying to build a dependency graph of tables based on the foreign keys between them. This graph needs to start with an arbitrary table name as its root. I could, give

相关标签:
2条回答
  • 2020-12-30 16:15

    Simplest way to do this is to copy all the FK info into a simple, 2-column (parent,child) table, and then use the following algorithm:

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

    that's all. Basically, you first print and remove all the nodes that don't depend on anything. After that being done, some other nodes will get free and you can repeat process.

    P.S. Make sure you don't insert self-referencing tables in the initial list (child=parent)

    0 讨论(0)
  • 2020-12-30 16:30
        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
    

    should work (replace the table name, of course) assuming that everything is in the same schema. Use the DBA_ versions of the data dictionary tables and conditions for the OWNER and R_OWNER columns if you need to handle cross-schema dependencies. On further reflection, this does not account for self-referential constraints (i.e. a constraint on the EMP table that the MGR column references the EMPNO column) either, so you'd have to modify the code to handle that case if you need to deal with self-referential constraints.

    For testing purposes, I added a few new tables to the SCOTT schema that also reference the DEPT table (including a grandchild dependency)

    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.
    

    and verified that the query returned the expected output

    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
    
    0 讨论(0)
提交回复
热议问题