8

複数のテーブル、ビュー、および関数を含む複雑なクエリがあります。関数とビューは、より多くのビューと関数に分割され、その中のより多くのビューと関数に分割される可能性があります。

このクエリにはパフォーマンスの問題があるため、クエリ内で参照されているすべてのオブジェクトの明確で簡潔なリストを取得して、調査の基礎を固めたいと考えています。このオブジェクトのリストを取得するにはどうすればよいですか?

4

6 に答える 6

8

説明

すべての依存する子オブジェクトと子の依存オブジェクトと子の子などを再帰的にリストするこのストアド プロシージャを以下に書きました。入力パラメーターは、Stored Proc、User Function、View です。オブジェクトが呼び出されたレベル、深さ、オブジェクトによってに関係なく、列 5 の一意のリストを取得するように簡単に変更できます。

  1. UsedByObjectId - 依存オブジェクトを使用する親オブジェクト
  2. UsedByObjectName - 親オブジェクトの名前
  3. UsedByObjectType - 親オブジェクトのタイプ (P、V、FN)
  4. DependentObjectId - 親が使用する子オブジェクト
  5. DependentObjectName - 子オブジェクトの名前
  6. DependentObjectType - 依存する子オブジェクトのタイプ (P、V、FN、U)
  7. Level - オブジェクトが使用されるネストされた再帰レベルの深さ

コード

--=========================================================================
--=========================================================================
--== 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 
于 2014-08-06T20:37:51.810 に答える
7

特定のシノニムを参照するすべてのオブジェクトを識別するためにこの投稿を見て、再帰 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;
于 2013-02-25T17:10:23.547 に答える
3

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という非常に便利なツールを使用することです。

于 2014-02-25T06:52:29.697 に答える