识别所有实体的所有依赖关系

时间:2013-08-01 20:00:08

标签: tsql sql-server-2005

我们正在升级我们的ERP系统,需要一种方法来识别架构更改可能已经破坏的过程,视图和功能。我们在与生产数据库相同的实例中的补充数据库中托管所有接口逻辑和支持实体。我需要一个脚本来收集新生产数据库中的所有表以及它们的字段,数据类型和大小,并将这些结果与补充数据库中的所有过程,视图和函数进行比较,并返回那些现在已被破坏的依赖项。有没有办法做到这一点?

1 个答案:

答案 0 :(得分:0)

2005年,这将非常艰难,因为sysdepends / sys.sql_dependencies is thoroughly broken和更好的依赖项功能直到SQL Server 2008才被添加。

我认为您可以通过重新编译所有视图,过程,函数和触发器两次来确保sysdepends是最新的(因为在第一次传递时仍可能存在延迟的名称解析问题等):

DECLARE @sql NVARCHAR(MAX); SET @sql = N'';

SELECT @sql = @sql + N'
EXEC sp_refreshview N''' + s.name + '.' + v.name + ''';'
  FROM sys.views AS v
  INNER JOIN sys.schemas AS s
  ON v.[schema_id] = s.[schema_id];

SELECT @sql = @sql + N'
EXEC sp_recompile N''' + s.name + '.' 
    + OBJECT_NAME(m.[object_id]) + ''';'
  FROM sys.sql_modules AS m
  INNER JOIN sys.objects AS o
  ON m.[object_id] = o.[object_id]
  INNER JOIN sys.schemas AS s
  ON o.[schema_id] = s.[schema_id]
  AND o.[type] IN (N'TR', N'FN', N'IF', N'P', N'TF');

PRINT @sql;
--EXEC sp_executesql @sql;

现在您可以对sysdepends / sys.sql_dependencies更加信任了,但为它们生成ALTER命令可能更好,因此它们会被主动重新编译而不是仅仅标记为重新编译。这假设您在CREATE <object>命令之前没有对评论感到满意,这些命令本身包含文本create。 (Wouldn't a way to generate ALTER commands be nice?或CREATE OR REPLACE的能力?)

DECLARE @sql NVARCHAR(MAX); SET @sql = N'';

SELECT @sql = @sql + N'
GO
' + STUFF(definition, CHARINDEX('CREATE', UPPER(definition)), 6, 'ALTER')
  FROM sys.sql_modules AS m
  INNER JOIN sys.objects AS o
  ON m.[object_id] = o.[object_id]
  INNER JOIN sys.schemas AS s
  ON o.[schema_id] = s.[schema_id]
  AND o.[type] IN (N'TR', N'FN', N'IF', N'P', N'TF');

PRINT @sql;
-- EXEC sp_executesql @sql;

完成后,您可以查看sys.sql_dependencies(在网格结果中效果最佳):

SELECT 
   s1.name + '.' + OBJECT_NAME(d.[object_id]),
  ' (' + o1.type_desc + ')',
  ' depends on => ',
  s2.name + '.' + OBJECT_NAME(d.referenced_major_id),
  ' (' + o2.type_desc + ')'
FROM sys.sql_dependencies AS d
INNER JOIN sys.objects AS o1
ON d.[object_id] = o1.[object_id]
INNER JOIN sys.schemas AS s1
ON o1.[schema_id] = s1.[schema_id]
INNER JOIN sys.objects AS o2
ON d.[referenced_major_id] = o2.[object_id]
INNER JOIN sys.schemas AS s2
ON o2.[schema_id] = s2.[schema_id];

sys.schemas的加入始终是必要的,因为虽然您可以使用OBJECT_SCHEMA_NAME(),但这在RTM中不可用,而且我不知道您在构建什么。如果您可以访问该功能,那么您可以简化其中一些连接。

另一个想法

您可以查看第三方工具,例如Red-Gate's SQL Dependency Tracker。我只是在外围看了它,这是很久以前的事了,所以我不能保证它,只是公司生产的工具才有用。