代码之家  ›  专栏  ›  技术社区  ›  Marcio Aguiar

存储过程反向工程

  •  12
  • Marcio Aguiar  · 技术社区  · 17 年前

    我们在工作中遇到了大量遗留存储过程的问题。你们有没有推荐任何能帮助更好理解这些程序的工具?一种反向工程,用于识别过程间依赖关系和/或过程与表之间的依赖关系。可以是免费的或商业的工具。

    谢谢!

    8 回复  |  直到 14 年前
        1
  •  4
  •   Chris Frederick    14 年前

    Redgate有一种相当昂贵的产品叫做 SQL Dependency Tracker 这似乎满足了要求。

        2
  •  6
  •   community wiki 8 revs ConcernedOfTunbridgeWells    17 年前

    比“依赖关系跟踪器”更便宜的解决方案是数据字典表sys.sql_dependencies,从中可以从数据字典查询此数据。Oracle有一个数据字典视图,具有类似的功能,称为dba_依赖项(加上等效的用户_u和所有_u视图)。使用其他数据字典表(sys.tables/dba_tables)等,可以生成对象依赖关系报告。

    如果您特别感兴趣,可以使用递归查询(OracleConnect By或SQL Server公共表表达式)来构建完整的对象依赖关系图。

    下面是一个有关sys.sql_依赖项的递归CTE示例。它将返回每个依赖项及其深度的条目。对于每个依赖关系,项可以多次发生,可能在不同的深度发生。我没有一个可供使用的Oracle实例来构建DBA依赖关系的“按连接查询”,因此任何具有编辑权限、时间和专业知识的人都可以对这个答案进行注释或编辑。

    还附注 sys.sql_dependencies 您可以从中获取列引用 referenced_minor_id . 这可以用于(例如)确定在临时区域的ETL存储过程中实际使用了哪些列,源数据库表的副本的列数超过实际使用的列数。

    with dep_cte as (
    select o2.object_id  as parent_id
          ,o2.name       as parent_name
          ,o1.object_id  as child_id
          ,o1.name       as child_name
          ,d.referenced_minor_id
          ,1 as hierarchy_level
      from sys.sql_dependencies d
      join sys.objects o1
        on o1.object_id = d.referenced_major_id
      join sys.objects o2
        on o2.object_id = d.object_id
     where d.referenced_minor_id in (0,1)
       and not exists
           (select 1
              from sys.sql_dependencies d2
             where d2.referenced_major_id = d.object_id)
    
    union all
    
    select o2.object_id  as parent_id
          ,o2.name       as parent_name
          ,o1.object_id  as child_id
          ,o1.name       as child_name
          ,d.referenced_minor_id
          ,d2.hierarchy_level + 1 as hierarchy_level
      from sys.sql_dependencies d
      join sys.objects o1
        on o1.object_id = d.referenced_major_id
      join sys.objects o2
        on o2.object_id = d.object_id
      join dep_cte d2
        on d.object_id = d2.child_id
     where d.referenced_minor_id in (0,1)
    )
    
    select *
      from dep_cte
     order by hierarchy_level
    

    我要把这个向社区开放。可以方便地访问正在运行的Oracle实例的人在这里通过递归查询发布连接吗?请注意,这是特定于SQL Server的,问题所有者已经明确表示他正在使用Oracle。我没有运行中的Oracle实例来开发和测试任何东西。

        3
  •  3
  •   Community Mohan Dere    9 年前

    我认为 Red Gate Dependency Tracker mentioned by rpetrich 是一个不错的解决方案,它很好地工作,红门有30天的审判(理想情况下足够长的时间,你做你的取证)。

    我也会考虑隔离系统并运行 SQL事件探查器,它将向您显示表上的所有SQL操作 . 这通常是 构建序列图的良好起点,或者您选择记录这些代码 . 祝你好运!

        4
  •  1
  •   JesseG    17 年前

    Redgate SQL文档生成的文档包含交叉引用的依赖关系信息。例如,对于每个表,它列出引用该表的视图、存储过程、触发器等。

        5
  •  1
  •   Mike McAllister    17 年前

    存储过程在哪个数据库中?Oracle,SQL Server,还有别的吗?

    基于注释编辑: 如果你使用的是Oracle,那么看看 TOAD . 我在其中使用了一个称为代码路线图的特性,它允许您以图形方式显示数据库中的PL/SQL跨部门。它可以在仅代码模式下运行,显示运行时调用堆栈依赖项,或者代码加数据模式,其中它还显示被代码触摸的数据库对象(表、视图、触发器)。

    (注意-我是一个蟾蜍用户,没有从中受益)

        6
  •  1
  •   Tim Cooper    14 年前

    这并不是很深入或彻底,但我认为如果您使用的是MS SQL Server或Oracle(也许Nigel可以帮助提供一个pl-sql示例),那么Nigel正在做一些事情。这只需要3个深度依赖项,但可以修改为需要的深度。这不是最漂亮的东西…但它很实用…

    select 
        so.name + case when so.xtype='P' then ' (Stored Proc)' when so.xtype='U' then ' (Table)' when so.xtype='V' then ' (View)' else ' (Unknown)' end as EntityName, 
        so2.name + case when so2.xtype='P' then ' (Stored Proc)' when so2.xtype='U' then ' (Table)' when so2.xtype='V' then ' (View)' else ' (Unknown)' end as FirstDependancy,
        so3.name + case when so3.xtype='P' then ' (Stored Proc)' when so3.xtype='U' then ' (Table)' when so3.xtype='V' then ' (View)' else ' (Unknown)' end as SecondDependancy,
        so4.name + case when so4.xtype='P' then ' (Stored Proc)' when so4.xtype='U' then ' (Table)' when so4.xtype='V' then ' (View)' else ' (Unknown)' end as ThirdDependancy
    from 
      sysdepends sd 
        inner join sysobjects as so on sd.id=so.id 
        left join sysobjects as so2 on sd.depid=so2.id
        left join sysdepends as sd2 on so2.id=sd2.id and so2.xtype not in ('S','PK','D')
        left join sysobjects as so3 on sd2.depid=so3.id and so3.xtype not in ('S','PK','D')
        left join sysdepends as sd3 on so3.id=sd3.id and so3.xtype not in ('S','PK','D')
        left join sysobjects as so4 on sd3.depid=so4.id and so4.xtype not in ('S','PK','D')
    where so.xtype = 'P' and left(so.name,2)<>'dt'
    group by so.name, so2.name, so3.name, so4.name, so.xtype, so2.xtype, so3.xtype, so4.xtype
    
        7
  •  1
  •   user423430    14 年前

    How to find the dependency chain of a database object (MS SQL Server 2000(?)+) 作者:雅各布·塞巴斯蒂安

    每次他需要部署新的报告或修改现有的 报告,他需要知道哪些数据库对象依赖于 给定的报表存储过程。有时报告非常 复杂,每个存储过程可能有几十个依赖项 对象和每个从属对象可能依赖于其他几十个 物体。

    他需要一种方法来递归地查找 给定的存储过程。我使用CTE编写了一个递归查询来实现 这个。

        8
  •  0
  •   Thomas Wagner    17 年前

    逆向工程的最佳工具是Apex。太神奇了。它甚至可以跟踪到.NET程序集并告诉您在哪里使用proc。它是迄今为止同类产品中最深的。Redgate有很多其他工具,但在本例中没有。

    推荐文章