查找列依赖项

问题描述 投票:15回答:9

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

例如:

表:SomeTable

Cols:col1 pk,col2,col3

我想找到所有依赖于col1的对象(Pk)

sql-server-2008 sql-server-2008-r2
9个回答
14
投票

尝试这个查询,它会得到一些我认为你正在寻找的结果。 要进行筛选,请在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'

13
投票

@ 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

我很想知道是否有人设法找到一种更好的方法,不会引入假阴性或阳性。


9
投票

这应该工作!

        -- 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

6
投票

只需替换{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

6
投票

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'

2
投票

试试这个:这将给出所有引用表格Pk的对象名称。

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

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


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%';

0
投票

它正在100%罚款。试着用这个。它会为您提供额外的细节。谢谢

选择

FK.TABLE_NAME AS Key_Table,

CU.COLUMN_NAME AS Foreignkey_Column,

PK.TABLE_NAME AS Primarykey_Table,

PT.COLUMN_NAME AS Primarykey_Column,

C.CONSTRAINT_NAME AS Constraint_Name

FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C

INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK

ON C.CONSTRAINT_NAME = Fk.CONSTRAINT_NAME

INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK

ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME

INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU

ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME

内部联接(选择

i1.TABLE_NAME,

i2.COLUMN_NAME

FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1

INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2

ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME

在哪里i1.CONSTRAINT_TYPE ='PRIMARY KEY')PT

在PT.TABLE_NAME = PK.TABLE_NAME上

在哪里PK.TABLE_NAME ='HRM_tbEmployee'

AND PT.COLUMN_NAME ='EmployeeID';

© www.soinside.com 2019 - 2024. All rights reserved.