存储过程逆向工程
我们在使用大量旧式存储过程时遇到了问题。你们推荐任何可以更好地理解这些程序的工具吗?某种反向工程,可识别过程间的依存关系和/或者过程与表的依存关系。可以是免费工具或者商业工具。
谢谢!
解决方案
回答
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还有很多其他工具,但在这种情况下没有。