Stored procedures reverse engineering

databaselegacyreverse-engineeringstored-procedures

We're having problem with a huge number of legacy stored procedures at work. Do you guys recommend any tool the can help better understand those procedures? Some kind of reverse engineering that indentifies inter-procedure dependencies and/or procedure vs. tables dependencies. Can be a free or commercial tool.

Thanks!

Best Solution

The cheaper solution than 'dependency tracker' is the data dictionary table sys.sql_dependencies which from which this data can be queried from the data dictionary. Oracle has a data dictionary view with similar functionality called DBA_DEPENDENCIES (plus equivalent USER_ and ALL_ views) . Using the other data dictionary tables (sys.tables/DBA_TABLES) etc. you can generate object dependency reports.

If you're feeling particularly keen you can use a recursive query (Oracle CONNECT BY or SQL Server Common Table Expressions) to build a complete object dependency graph.

Here's an example of a recursive CTE on sys.sql_dependencies. It will return an entry for every dependency with its depth. Items can occur more than once, possibly at different depths, for every dependency relationship. I don't have a working Oracle instance to hand to build a CONNECT BY query on DBA_DEPENDENCIES so anyone with edit privileges and the time and expertise is welcome to annotate or edit this answer.

Note also with sys.sql_dependencies that you can get column references from referenced_minor_id. This could be used (for example) to determine which columns were actually used in the ETL sprocs from a staging area with copies of the DB tables from the source with more columns than are actually used.

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

I've got this to open-up to the community now. Could someone with convenient access to a running Oracle instance post a CONNECT BY recursive query here? Note that this is SQL-server specific and the question owner has since made it clear that he's using Oracle. I don't have a running Oracle instance to hand to develop and test anything.