Ну, я сделал что-то на основе этой статьи
Я изменил sp_FindDependencies, чтобы включить уровень в дерево зависимостей:
CREATE PROCEDURE sp_FindDependencies
(
@ObjectName SYSNAME,
@ObjectType VARCHAR(5) = NULL
)
AS
BEGIN
DECLARE @ObjectID AS BIGINT
SELECT TOP(1) @ObjectID = object_id
FROM sys.objects
WHERE name = @ObjectName
AND type = ISNULL(@ObjectType, type)
SET NOCOUNT ON ;
WITH DependentObjectCTE (DependentObjectID, DependentObjectName, ReferencedObjectName, ReferencedObjectID, Level)
AS
(
SELECT DISTINCT
sd.object_id,
OBJECT_NAME(sd.object_id),
ReferencedObject = OBJECT_NAME(sd.referenced_major_id),
ReferencedObjectID = sd.referenced_major_id,
1 AS Level
FROM
sys.sql_dependencies sd
JOIN sys.objects so ON sd.referenced_major_id = so.object_id
WHERE
sd.referenced_major_id = @ObjectID
UNION ALL
SELECT
sd.object_id,
OBJECT_NAME(sd.object_id),
OBJECT_NAME(referenced_major_id),
object_id,
Level + 1
FROM
sys.sql_dependencies sd
JOIN DependentObjectCTE do ON sd.referenced_major_id = do.DependentObjectID
WHERE
sd.referenced_major_id <> sd.object_id
)
SELECT DISTINCT
DependentObjectName, Level
FROM
DependentObjectCTE c
END
GO
Затем я прошёлвсе объекты, которые я хочу отследить.В моей системе я поддерживаю версию этих объектов в таблице SpVersion.
DECLARE @err int;
DECLARE @level int;
DECLARE @name varchar(50);
DECLARE @name2 varchar(50);
DECLARE cur CURSOR LOCAL FAST_FORWARD FOR
SELECT SP.name AS obj_name
FROM sys.procedures SP, SpVersion SPV WHERE
SP.name = SPV.SpName
UNION
SELECT SO.name AS obj_name
FROM sys.objects SO, SpVersion SPV
WHERE type_desc LIKE '%FUNCTION%' AND SO.name=SPV.SpName
UNION
SELECT ST.name AS obj_name
FROM sys.triggers ST, SpVersion SPV
WHERE ST.name=SPV.SpName;
CREATE TABLE #T1 (procname varchar(50) COLLATE DATABASE_DEFAULT, Level int);
CREATE TABLE #T2 (procname varchar(50) COLLATE DATABASE_DEFAULT, Level int);
OPEN cur
SELECT @err = @@error IF @err <> 0 RETURN
WHILE 1=1 BEGIN
FETCH NEXT FROM cur INTO @name
SELECT @err = @@error IF @err <> 0 RETURN
IF @@FETCH_STATUS <> 0 BREAK
DELETE #T1;
INSERT #T1 (procname, level) VALUES (@name, 0);
INSERT #T1 (procname, level) EXEC sp_FindDependencies @name;
DECLARE cur2 CURSOR LOCAL FAST_FORWARD FOR
SELECT procname, level FROM #T1;
OPEN cur2
SELECT @err = @@error IF @err <> 0 RETURN
WHILE 1=1 BEGIN
FETCH NEXT FROM cur2 INTO @name2, @level
SELECT @err = @@error IF @err <> 0 RETURN
IF @@FETCH_STATUS <> 0 BREAK
PRINT @name;
PRINT CONVERT(nvarchar, @level)
IF NOT EXISTS(SELECT 1 FROM #T2 WHERE procname = @name) BEGIN
INSERT INTO #T2 (procname, level) VALUES (@name, @level);
END ELSE BEGIN
UPDATE #T2 SET level=@level WHERE procname=@name;
END
END
CLOSE cur2;
DEALLOCATE cur2;
END
CLOSE cur;
DEALLOCATE cur;
SELECT * FROM #T2 ORDER BY Level DESC;
DROP TABLE #T1
DROP TABLE #T2
GO