2012-08-01 170 views
11

如何查找依赖于特定列表的对象。查找列依赖关系

例:

表:SomeTable

列数: COL1 PK, COL2, COL3

我想找到所有这些都依赖于COL1的对象(PK)

回答

10

尝试此查询,它可以把你的一些结果,我认为你正在寻找。
要过滤,请在c1.name或c2.name列中搜索值。
要查找所有引用某列,使用c2.name对于列名和OBJECT_NAME(k.referenced_object_id)当保持C2列:)

好运表!


    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 2017-12-07 03:36:37

+0

我更改了缺少连接条件的脚本。有趣的是,在更多的5年后,这个脚本仍然使用:) – 2017-12-07 12:30:16

+0

你不知道我昨天发现它有多么有用! :-) – gerrod 2017-12-07 19:44:24

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

这就是我之后,谢谢 – 2017-06-20 10:41:30

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

请问在这种情况下'1 by Order'做什么? – Peter 2015-11-12 09:40:37

+1

它会按升序排列第一列的结果。 – 2015-11-17 06:56:35

+0

谢谢@Arpan,我不知道! – Peter 2015-11-17 07:44:26

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之间的附加连接条件。见行开头“和”下面:

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 

以供参考,在这里是一个与修订了整个脚本加入:

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 2016-06-15 17:56:19

4

@ NoFuchsGavin的剧本通常的伟大工程,但有一定的局限性,由于与sysdepends问题(有关这会给出不正确结果的示例,请参见this blog post by Pinal Dave)。

Microsoft还建议您避免在新开发工作中使用sysdepends

因此,我们可以使用sys.dm_sql_referencing_entitiessys.dm_sql_referenced_entities作为建议here

但是我注意到,由于referenced_minor_name为NULL,有时会排除列引用。因此,我添加了另一个可能引入误报的条件,但确保列引用不会从结果集中省略。

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 2017-05-19 01:36:54