加入收藏 | 设为首页 | 会员中心 | 我要投稿 天津站长网 (https://www.022zz.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

sql – 使用递归查询构建表依赖关系图

发布时间:2021-03-31 12:23:32 所属栏目:MsSql教程 来源:网络整理
导读:我正在尝试基于它们之间的外键构建表的依赖关系图.此图需要以任意表名作为其根开始.我可以,给定一个表名查找使用all_constraints视图引用它的表,然后查找引用它们的表,依此类推,但这将是非常低效的.我写了一个递归查询,为所有表执行此操作,但是当我添加:

我正在尝试基于它们之间的外键构建表的依赖关系图.此图需要以任意表名作为其根开始.我可以,给定一个表名查找使用all_constraints视图引用它的表,然后查找引用它们的表,依此类推,但这将是非常低效的.我写了一个递归查询,为所有表执行此操作,但是当我添加:

START WITH Table_Name=:tablename

它不会返回整个树.

解决方法

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

应该工作(当然,替换表名),假设一切都在同一个模式中.如果需要处理跨模式依赖关系,请使用OWNER和R_OWNER列的数据字典表和条件的DBA_版本.进一步反思,这不考虑自引用约束(即MMP列引用EMPNO列的EMP表上的约束),因此如果需要处理,则必须修改代码以处理该情况具有自我约束的约束.

出于测试目的,我向SCOTT模式添加了一些新表,这些表也引用了DEPT表(包括孙子依赖项)

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.

并验证查询返回了预期的输出

SQL> ed
Wrote file afiedt.buf

  1  select parent,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

(编辑:天津站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读