2012-08-01 15 views
11

表の特定の列に依存するオブジェクトの検索方法。列の依存関係の検索

例:

表:SomeTable

Colsは: COL1 PK、 COL2、 col3という

私はCOL1に依存するすべてのオブジェクト(PK)

答えて

10

このクエリを試すと、探していると思われる結果が表示されます。
フィルタリングするには、c1.nameまたはc2.name列の値を検索します。
C2列を保持するテーブルとカラム名とOBJECT_NAME(k.referenced_object_id)のためc2.nameを使用し、特定の列へのすべての参照を探しするには:)

グッドラック!


    select OBJECT_NAME(k.parent_object_id) as parentTable 
      , c1.name as parentColumn 
      , OBJECT_NAME(k.referenced_object_id) as referencedTable 
      , c2.name as referencedColumn 
    from sys.foreign_keys k 
      inner join sys.foreign_key_columns f 
       on f.parent_object_id = k.parent_object_id 
       and f.constraint_object_id = k.object_id 
      inner join sys.columns c1 
       on c1.column_id = f.parent_column_id 
       and c1.object_id = k.parent_object_id 
      inner join sys.columns c2 
       on c2.column_id = f.referenced_column_id 
       and c2.object_id = k.referenced_object_id 
    where c2.name = 'Column' 
    and  OBJECT_NAME(k.referenced_object_id) = 'Table' 
+0

注 - これには結合条件がありません。@ christopher-cullumの下の修正されたスクリプトを参照してください。 – gerrod

+0

不足している結合条件でスクリプトを変更しました。面白いことに、5年後にこのスクリプトはまだ使用されています:) –

+0

あなたは私が昨日それを見つけたことがどれほど役に立つか分かりません!! :-) – gerrod

1
を見つけたいです

これを試してください:これはあなたのテーブルのPkを参照しているすべてのオブジェクト名を与えます。

select OBJECT_NAME(parent_object_id) from sys.foreign_keys where referenced_object_id = OBJECT_ID('YourTableName') 
5

{0}と{1}を単に交換してください。

declare @tbl_nme as varchar(50) 
declare @col_nme as varchar(50) 
declare @level int 
set @level = 1 
set @tbl_nme= '{0}' --TableName 
set @col_nme= '{1}' --ColumnName 



select 
    obj.name as obj_nm 
, col.name as col_nm 
, depobj.name as dep_obj_nm 
, CASE depobj.type 
    WHEN 'C' THEN 'CHECK constraint' 
    WHEN 'D' THEN 'Default' 
    WHEN 'F' THEN 'FOREIGN KEY' 
    WHEN 'FN' THEN 'Scalar function' 
    WHEN 'IF' THEN 'In-lined table-function' 
    WHEN 'K' THEN 'PRIMARY KEY' 
    WHEN 'L' THEN 'Log' 
    WHEN 'P' THEN 'Stored procedure' 
    WHEN 'R' THEN 'Rule' 
    WHEN 'RF' THEN 'Replication filter stored procedure' 
    WHEN 'S' THEN 'System table' 
    WHEN 'TF' THEN 'Table function' 
    WHEN 'TR' THEN 'Trigger' 
    WHEN 'U' THEN 'User table' 
    WHEN 'V' THEN 'View' 
    WHEN 'X' THEN 'Extended stored procedure' 
    END as dep_obj_type 
, null as dep_col_nm 
, depobj.type as dep_obj_typeID 
, @level as level 
into #temp 
from sysobjects obj 
    join syscolumns col on obj.id = col.id 
    left join (sysdepends dep join sysobjects depobj on depobj.id = dep.id) 
     on obj.id = dep.depid 
     and col.colid = dep.depnumber 
where obj.name = @tbl_nme 
    and col.name = @col_nme 


while (@@rowcount > 0) 
begin 
set @level = @level + 1 
insert into #temp 
select 
    obj.name as obj_nm 
, col.name as col_nm 
, depobj.name as dep_obj_nm 
, CASE depobj.type 
    WHEN 'C' THEN 'CHECK constraint' 
    WHEN 'D' THEN 'Default' 
    WHEN 'F' THEN 'FOREIGN KEY' 
    WHEN 'FN' THEN 'Scalar function' 
    WHEN 'IF' THEN 'In-lined table-function' 
    WHEN 'K' THEN 'PRIMARY KEY' 
    WHEN 'L' THEN 'Log' 
    WHEN 'P' THEN 'Stored procedure' 
    WHEN 'R' THEN 'Rule' 
    WHEN 'RF' THEN 'Replication filter stored procedure' 
    WHEN 'S' THEN 'System table' 
    WHEN 'TF' THEN 'Table function' 
    WHEN 'TR' THEN 'Trigger' 
    WHEN 'U' THEN 'User table' 
    WHEN 'V' THEN 'View' 
    WHEN 'X' THEN 'Extended stored procedure' 
    END as dep_obj_type 
, null as dep_col_nm 
, depobj.type as dep_obj_typeID 
, @level as level 
from sysobjects obj 
    join syscolumns col on obj.id = col.id 
    left join (sysdepends dep join sysobjects depobj on depobj.id = dep.id) 
     on obj.id = dep.depid 
     and col.colid = dep.depnumber 
where exists(select 1 from #temp a where obj.name = a.dep_obj_nm and 
col.name = a.dep_col_nm and level = @level - 1 and dep_col_nm is not null) 
end 

select 
    obj_nm AS 'TABLE', 
    col_nm AS 'COLUMN', 
    dep_obj_nm AS 'USAGE_OBJECT', 
    dep_obj_type AS 'USAGE_OBJECTTYPE', 
    dep_obj_typeID AS 'USAGE_OBJECTTYPEID' 
from #temp 
drop table #temp 
+0

これは私が後にしたことです、ありがとう –

0

これはトリックを行う必要があります。

SELECT OBJECT_NAME (referencing_id), referencing_id, referenced_id 
FROM sys.sql_expression_dependencies d 
WHERE OBJECT_NAME(d.referenced_id) = '<TABLE_NAME>' 
     AND OBJECT_DEFINITION(referencing_id) = '<COLUMN_NAME>'; 

ソース:http://www.mssqltips.com/sqlservertip/2999/different-ways-to-find-sql-server-object-dependencies/

または、

EXEC sp_depends <TABLE_NAME> 

ソースを使用、テーブルの上にすべての依存関係を表示する:https://msdn.microsoft.com/en-us/library/ms189487.aspx

8

これはうまくいくはずです!

 -- Search in All Objects 
SELECT OBJECT_NAME(OBJECT_ID),definition 
FROM sys.sql_modules 
WHERE definition LIKE '%' + 'ColumnToBeSearched' + '%' 
Order by 1 
GO 

-- Search in Stored Procedure Only 
SELECT DISTINCT OBJECT_NAME(OBJECT_ID), 
object_definition(OBJECT_ID) 
FROM sys.Procedures 
WHERE object_definition(OBJECT_ID) LIKE '%' + 'ColumnToBeSearched' + '%' 
GO 
+0

この場合、 'Order by 1'はどうしたらいいですか? – Peter

+1

最初の列の結果セットを昇順に並べ替えます。 –

+0

ありがとう@アルパン、私はそれを知らなかった! – Peter

0

検索特定の列の依存

 
SELECT OBJECT_NAME(referencing_id), 
    referenced_database_name, 
    referenced_schema_name, 
    referenced_entity_name 
FROM sys.sql_expression_dependencies 
WHERE OBJECT_NAME(referenced_id) = 'table_name' 
    AND OBJECT_DEFINITION(referencing_id) LIKE '%field_name%'; 
3

accepted answer aboveに設けられたSQLはsys.foreign_keysとsys.foreign_key_columnsの間に追加の結合条件を含むべきです。行で始まる「と」下記を参照してください:

select OBJECT_NAME(k.parent_object_id) as parentTable 
     , c1.name as parentColumn 
     , OBJECT_NAME(k.referenced_object_id) as referencedTable 
     , c2.name as referencedColumn 
from sys.foreign_keys k 
     inner join sys.foreign_key_columns f 
      on f.parent_object_id = k.parent_object_id 
      and f.constraint_object_id = k.object_id 
     inner join sys.columns c1 
      on c1.column_id = f.parent_column_id 
      and c1.object_id = k.parent_object_id 
     inner join sys.columns c2 
      on c2.column_id = f.referenced_column_id 
      and c2.object_id = k.referenced_object_id 
where c2.name = 'GUID' 
and  OBJECT_NAME(k.referenced_object_id) = 'AuthDomain' 
+1

あなたの答えは一人一人にしてください - 誰も受け入れられた答えを読んだことがないと仮定してください。 – rrauenza

4

をNoFuchsGavinのスクリプト@通常素晴らしい作品が、sysdependsとの問題のために、いくつかの制限があります。参考のために

from sys.foreign_keys k 
     inner join sys.foreign_key_columns f 
      on f.parent_object_id = k.parent_object_id 
       and f.constraint_object_id = k.object_id 

を、ここでの改正に参加して全体のスクリプトがあります(これが不正確な結果をもたらす例については、this blog post by Pinal Daveを参照してください)。

Microsoftまた、新しい開発作業でsysdependsを使用しないことをお勧めします。

したがって、hereとしてsys.dm_sql_referencing_entitiessys.dm_sql_referenced_entitiesを使用することができます。

しかし、これはNULLがreferenced_minor_nameであるために列参照が除外されることがあります。したがって、誤検出を導入する可能性があるが、列参照が結果セットから省略されないようにする別の条件を追加しました。スクリプト上

DECLARE @SchemaName sysname = '{0}'; 
DECLARE @TableName sysname = '{1}'; 
DECLARE @ColumnName sysname = '{2}'; 

SELECT 
    @SchemaName + '.' + @TableName          AS [USED_OBJECT], 
    @ColumnName               AS [COLUMN], 
    referencing.referencing_schema_name + '.' + referencing_entity_name AS USAGE_OBJECT, 
    CASE so.type 
     WHEN 'C' THEN 'CHECK constraint' 
     WHEN 'D' THEN 'Default' 
     WHEN 'F' THEN 'FOREIGN KEY' 
     WHEN 'FN' THEN 'Scalar function' 
     WHEN 'IF' THEN 'In-lined table-function' 
     WHEN 'K' THEN 'PRIMARY KEY' 
     WHEN 'L' THEN 'Log' 
     WHEN 'P' THEN 'Stored procedure' 
     WHEN 'R' THEN 'Rule' 
     WHEN 'RF' THEN 'Replication filter stored procedure' 
     WHEN 'S' THEN 'System table' 
     WHEN 'TF' THEN 'Table function' 
     WHEN 'TR' THEN 'Trigger' 
     WHEN 'U' THEN 'User table' 
     WHEN 'V' THEN 'View' 
     WHEN 'X' THEN 'Extended stored procedure' 
    END            AS USAGE_OBJECTTYPE, 
    so.[type]          AS USAGE_OBJECTTYPEID 
FROM sys.dm_sql_referencing_entities 
    (
     @SchemaName + '.' + @TableName, 
     'object' 
    ) referencing 
    INNER JOIN sys.objects so 
     ON referencing.referencing_id = so.object_id 
WHERE 
    EXISTS 
    (
     SELECT 
      * 
     FROM 
      sys.dm_sql_referenced_entities 
      (
       referencing_schema_name + '.' + referencing_entity_name, 
       'object' 
      ) referenced 
     WHERE 
      referenced_entity_name = @TableName 
      AND 
      (
       referenced.referenced_minor_name LIKE @ColumnName 
       -- referenced_minor_name is sometimes NULL 
       -- therefore add below condition (can introduce False Positives) 
       OR 
       (
        referenced.referenced_minor_name IS NULL 
        AND 
        OBJECT_DEFINITION 
        (
         OBJECT_ID(referencing_schema_name + '.' + referencing_entity_name) 
        ) LIKE '%' + @ColumnName + '%' 
       ) 
      ) 
    ) 
ORDER BY 
    USAGE_OBJECTTYPE, 
    USAGE_OBJECT 

NoFuchsGavinの答えとthis blog post @に基づいています。

誰かが偽陰性または陽性を導入しないより良い方法を見つけることができたかどうかを知りたいと思っています。

+0

私のために働く!ベストプラクティスを参照してくれてありがとう! – Colin