複数のテーブル、ビュー、および関数を含む複雑なクエリがあります。関数とビューは、より多くのビューと関数に分割され、その中のより多くのビューと関数に分割される可能性があります。
このクエリにはパフォーマンスの問題があるため、クエリ内で参照されているすべてのオブジェクトの明確で簡潔なリストを取得して、調査の基礎を固めたいと考えています。このオブジェクトのリストを取得するにはどうすればよいですか?
複数のテーブル、ビュー、および関数を含む複雑なクエリがあります。関数とビューは、より多くのビューと関数に分割され、その中のより多くのビューと関数に分割される可能性があります。
このクエリにはパフォーマンスの問題があるため、クエリ内で参照されているすべてのオブジェクトの明確で簡潔なリストを取得して、調査の基礎を固めたいと考えています。このオブジェクトのリストを取得するにはどうすればよいですか?
説明
すべての依存する子オブジェクトと子の依存オブジェクトと子の子などを再帰的にリストするこのストアド プロシージャを以下に書きました。入力パラメーターは、Stored Proc、User Function、View です。オブジェクトが呼び出されたレベル、深さ、オブジェクトによってに関係なく、列 5 の一意のリストを取得するように簡単に変更できます。
列
コード
--=========================================================================
--=========================================================================
--== utlGetAllDependentObjectsRecursive - Uses recursive common table
--== expression to recursively get all the dependent objects as well
--== as the child objects and child's child objects of a
--== Stored Procedure or View or Function. can be easily modified to
--== include all other types of Objects
--=========================================================================
--=========================================================================
CREATE PROCEDURE utlGetAllDependentObjectsRecursive
(
-- Supports Stored Proc, View, User Function, User Table
@PARAM_OBJECT_NAME VARCHAR(500)
)
AS
BEGIN
WITH CTE_DependentObjects AS
(
SELECT DISTINCT
b.object_id AS UsedByObjectId,
b.name AS UsedByObjectName, b.type AS UsedByObjectType,
c.object_id AS DependentObjectId,
c.name AS DependentObjectName , c.type AS DependenObjectType
FROM sys.sysdepends a
INNER JOIN sys.objects b ON a.id = b.object_id
INNER JOIN sys.objects c ON a.depid = c.object_id
WHERE b.type IN ('P','V', 'FN') AND c.type IN ('U', 'P', 'V', 'FN')
),
CTE_DependentObjects2 AS
(
SELECT
UsedByObjectId, UsedByObjectName, UsedByObjectType,
DependentObjectId, DependentObjectName, DependenObjectType,
1 AS Level
FROM CTE_DependentObjects a
WHERE a.UsedByObjectName = @PARAM_OBJECT_NAME
UNION ALL
SELECT
a.UsedByObjectId, a.UsedByObjectName, a.UsedByObjectType,
a.DependentObjectId, a.DependentObjectName, a.DependenObjectType,
(b.Level + 1) AS Level
FROM CTE_DependentObjects a
INNER JOIN CTE_DependentObjects2 b
ON a.UsedByObjectName = b.DependentObjectName
)
SELECT DISTINCT * FROM CTE_DependentObjects2
ORDER BY Level, DependentObjectName
END
特定のシノニムを参照するすべてのオブジェクトを識別するためにこの投稿を見て、再帰 CTE で回答の基本ロジックを使用して、実行中の最上位クエリ内のオブジェクトのコンマ区切りリストに関連するすべてのオブジェクトを識別しました。
Declare @baseObjects Nvarchar(1000) = '[Schema].[Table],[Schema].[View],[Schema].[Function],[Schema].[StoredProc]',
@SQL Nvarchar(Max);
Declare @objects Table (SchemaName Varchar(512), TableName Varchar(512), ID Int, xtype Varchar(10));
Set @SQL = 'Select ss.name As SchemaName,
so.name As TableName,
so.id,
so.xtype
From sysobjects so
Join sys.schemas ss
On so.uid = ss.schema_id
Where so.id In (Object_ID(''' + Replace(@baseObjects,',','''),Object_ID(''') + '''))';
Insert @objects
Exec sp_executeSQL @SQL;
With test As
(
Select ss.name As SchemaName,
so.name As TableName,
so.id,
so.xtype
From sys.sql_expression_dependencies sed
Join @objects vo
On sed.referencing_id = vo.ID
Join sysobjects so
On sed.referenced_id = so.id
Join sys.schemas ss
On so.uid = ss.schema_id
Union All
Select ss.name As SchemaName,
so.name As TableName,
so.id,
so.xtype
From test
Join sys.sql_expression_dependencies sed
On sed.referencing_id = test.id
And sed.referencing_id <> sed.referenced_id
Join sysobjects so
On sed. referenced_id = so.id
Join sys.schemas ss
On so.uid = ss.schema_id
)
Select Distinct *
From test
Union
Select *
From @objects;
SQL Server 2008 には、オブジェクトの依存関係を追跡するために導入された 2 つの新しい動的管理関数があります。
1/ 特定のエンティティを参照するエンティティを返す:
SELECT
referencing_schema_name, referencing_entity_name,
referencing_class_desc, is_caller_dependent
FROM sys.dm_sql_referencing_entities ('<TableName>', 'OBJECT')
2/ オブジェクトによって参照されるエンティティを返す:
SELECT
referenced_schema_name, referenced_entity_name, referenced_minor_name,
referenced_class_desc, is_caller_dependent, is_ambiguous
FROM sys.dm_sql_referenced_entities ('<StoredProcedureName>', 'OBJECT');
もう 1 つのオプションは、Red Gate のSQL Dependency Trackerという非常に便利なツールを使用することです。