存储过程逆向工程

时间:2020-03-05 18:55:17  来源:igfitidea点击:

我们在使用大量旧式存储过程时遇到了问题。你们推荐任何可以更好地理解这些程序的工具吗?某种反向工程,可识别过程间的依存关系和/或者过程与表的依存关系。可以是免费工具或者商业工具。

谢谢!

解决方案

回答

Redgate有一个相当昂贵的产品,称为SQL Dependency Tracker,似乎可以满足要求。

回答

我认为rpetrich提到的Red Gate Dependency Tracker是一个不错的解决方案,它运作良好,并且Red Gate有30天的试用期(理想的时间足够我们进行取证)。

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

回答

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

回答

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

根据评论进行编辑:既然我们正在使用Oracle,请查看TOAD。我在其中使用了一个称为"代码路线图"的功能,该功能可让我们以图形方式显示数据库中的PL / SQL相互依赖关系。它可以在"仅代码"模式下运行,以显示运行时调用堆栈的相关性,也可以在"代码加数据"模式下运行,在该模式下,它还可以显示代码所触及的数据库对象(表,视图,触发器)。

(请注意,我是TOAD用户,引用它不会有任何好处)

回答

比"依赖跟踪器"便宜的解决方案是数据字典表sys.sql_dependencies,可以从数据字典中查询该数据。 Oracle具有称为DBA_DEPENDENCIES的具有类似功能的数据字典视图(以及等效的USER_和ALL_视图)。使用其他数据字典表(sys.tables / DBA_TABLES)等,可以生成对象相关性报告。

如果我们特别热衷,可以使用递归查询(Oracle CONNECT BY或者SQL Server通用表表达式)来构建完整的对象依赖关系图。

这是sys.sql_dependencies上递归CTE的示例。它将为每个依赖项及其深度返回一个条目。对于每个依赖关系,项目可能会出现不止一次,可能发生在不同的深度。我没有可用的Oracle实例来在DBA_DEPENDENCIES上构建CONNECT BY查询,因此,欢迎任何具有编辑特权,时间和专业知识的人注释或者编辑此答案。

还要注意,使用sys.sql_dependencies可以从referenced_minor_id获取列引用。例如,可以使用它来确定登台区域中的ETL proc中实际使用了哪些列,而源中的DB表副本比实际使用的列多。

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实例的人可以在此处发布CONNECT BY递归查询吗?请注意,这是特定于SQL Server的,此后问题所有者明确表示他正在使用Oracle。我没有正在运行的Oracle实例来开发和测试任何东西。

回答

这不是真正的深入或者全面的知识,但是我认为,如果我们使用的是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

回答

逆向工程的最佳工具是APEX。太奇妙了。它甚至可以追溯到.NET程序集,并告诉我们proc的使用位置。迄今为止,它是同类产品中最深的产品。 RedGate还有很多其他工具,但在这种情况下没有。