【问题标题】:How can I find out what FOREIGN KEY constraint references a table in SQL Server?如何找出引用 SQL Server 中表的 FOREIGN KEY 约束?
【发布时间】:2013-07-04 07:43:12
【问题描述】:

我正在尝试删除表格,但收到以下消息:

消息 3726,第 16 级,状态 1,第 3 行
无法删除对象“dbo.UserProfile”,因为它被 FOREIGN KEY 约束引用。
消息 2714,第 16 级,状态 6,第 2 行
数据库中已经有一个名为“UserProfile”的对象。

我使用 SQL Server Management Studio 环顾四周,但找不到约束。如何找出外键约束?

【问题讨论】:

  • 我喜欢 sp_help 'dbo.TableName' 更多方法请看这里:stackoverflow.com/questions/483193/…
  • Worth noticing: @LittleSweetSeas 的回答将返回有关给定 引用表 的外键 FOR 的信息,但是 @Gayathri-Varma 的回答给定父表的详细信息。两者在不同的情况下都很有用,并且都赢得了自己的比赛:-)

标签: sql sql-server sql-server-2008


【解决方案1】:

这里是:

SELECT 
   OBJECT_NAME(f.parent_object_id) TableName,
   COL_NAME(fc.parent_object_id,fc.parent_column_id) ColName
FROM 
   sys.foreign_keys AS f
INNER JOIN 
   sys.foreign_key_columns AS fc 
      ON f.OBJECT_ID = fc.constraint_object_id
INNER JOIN 
   sys.tables t 
      ON t.OBJECT_ID = fc.referenced_object_id
WHERE 
   OBJECT_NAME (f.referenced_object_id) = 'YourTableName'

这样,您将获得引用表和列名。

根据评论建议,编辑为使用 sys.tables 而不是通用 sys.objects。 谢谢,marc_s

【讨论】:

  • 你应该使用更专注的sys.tables而不是sys.objects
  • @marc_s:谢谢你,但你能举个例子吗? sys.tables 中的 AFAIK 我没有 FK 引用
  • 我的意思是:只需将INNER JOIN sys.objects AS o ON o.OBJECT_ID = fc.referenced_object_id 替换为INNER JOIN sys.tables t ON t.OBJECT_ID = fc.referenced_object_id
  • @LittleSweetSeas 我已经运行了上面的查询,但我没有得到具有外键约束的表的对象名和列名
  • 您可以通过更多信息来加强您的选择:SELECT f.name ConstraintName, f.type_desc ConstraintType, OBJECT_NAME(f.parent_object_id) ConstrainedTable, COL_NAME(fc.parent_object_id, fc.parent_column_id) ConstrainedColumn , OBJECT_NAME(f.referenced_object_id) ReferencedTable, COL_NAME(fc.referenced_object_id, fc.referenced_column_id) ReferencedColumn
【解决方案2】:

另一种方法是检查结果

sp_help 'TableName'

(或者只是突出显示引用的 TableName 并按 ALT+F1)

随着时间的推移,我决定完善我的答案。下面是sp_help 提供的结果截图。 A 在此示例中使用了 AdventureWorksDW2012 数据库。那里有很多很好的信息,而我们正在寻找的是最后 - 以绿色突出显示:

【讨论】:

  • +1 这提供了很多有用的信息,并且在输出底部显示了外键
  • 这用最少的代码行数给了我很多信息
  • 这是最酷的捷径!完全击败 Ctl-R 刷新架构!
  • 刷新本地 InteliSense 缓存 = Ctrl+Shift+R; Ctrl+R = 显示/隐藏结果窗格(或者至少这些是我对 SSMS2008 和 SSMS2014 的默认设置)
【解决方案3】:

试试这个

SELECT
  object_name(parent_object_id) ParentTableName,
  object_name(referenced_object_id) RefTableName,
  name 
FROM sys.foreign_keys
WHERE parent_object_id = object_id('Tablename')

【讨论】:

  • 短而优雅,适合我!唯一的问题是返回的name 值是一个内部名称(methinks),而不是父表中的实际列名。有什么办法解决这个问题?
  • 我在这里看到ParentTableName 总是与where 子句中给定的'Tablename' 相同(如果包括)。这可能是故意的,并且在查询多个表时会更有用。
【解决方案4】:

我发现这个答案很简单,并做了我需要的技巧:https://stackoverflow.com/a/12956348/652519

来自链接的摘要,请使用以下查询:

EXEC sp_fkeys 'TableName'

快速简单。我能够很快找到 15 个表的所有外键表、各自的列和外键名称。

正如下面@mdisibio 所指出的,这里是详细说明可以使用的不同参数的文档的链接:https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-fkeys-transact-sql

【讨论】:

  • 还有五个其他参数需要过滤,其中最有用的是您可以指定非默认模式的第二个参数,例如EXEC sp_fkeys 'Payroll', 'accounting'
【解决方案5】:

这是找出所有数据库中外键关系的最佳方法。

exec sp_helpconstraint 'Table Name'

还有一种方法

select * from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME='Table Name'
--and left(CONSTRAINT_NAME,2)='FK'(If you want single key)

【讨论】:

  • 这个解决方案exec sp_helpconstraint 'Table Name' 是唯一一个为我返回任何行的解决方案。然而,约束名称是胡言乱语。 PRIMARY KEY (clustered) PK__org_soft__3213E83FE6B07364
  • 这只有在您有足够的权限访问表信息架构时才有效
【解决方案6】:

我正在使用此脚本来查找与外键相关的所有详细信息。 我正在使用 INFORMATION.SCHEMA。 下面是一个 SQL 脚本:

SELECT 
    ccu.table_name AS SourceTable
    ,ccu.constraint_name AS SourceConstraint
    ,ccu.column_name AS SourceColumn
    ,kcu.table_name AS TargetTable
    ,kcu.column_name AS TargetColumn
FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu
    INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
        ON ccu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME 
    INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu 
        ON kcu.CONSTRAINT_NAME = rc.UNIQUE_CONSTRAINT_NAME  
ORDER BY ccu.table_name

【讨论】:

  • 我正在寻找一种方法来查看作为外键的列以及该列引用的相关表,这很好地总结了它。谢谢!
  • 这在我的一些表上丢失了一些外键,而@LittleSweetSeas answer 显示了它们
【解决方案7】:

如果你想通过对象资源管理器窗口中的 SSMS,右键单击你要删除的对象,查看依赖关系。

【讨论】:

    【解决方案8】:
    SELECT 
        obj.name      AS FK_NAME,
        sch.name      AS [schema_name],
        tab1.name     AS [table],
        col1.name     AS [column],
        tab2.name     AS [referenced_table],
        col2.name     AS [referenced_column]
    FROM 
         sys.foreign_key_columns fkc
    INNER JOIN sys.objects obj
        ON obj.object_id = fkc.constraint_object_id
    INNER JOIN sys.tables tab1
        ON tab1.object_id = fkc.parent_object_id
    INNER JOIN sys.schemas sch
        ON tab1.schema_id = sch.schema_id
    INNER JOIN sys.columns col1
        ON col1.column_id = parent_column_id AND col1.object_id = tab1.object_id
    INNER JOIN sys.tables tab2
        ON tab2.object_id = fkc.referenced_object_id
    INNER JOIN sys.columns col2
        ON col2.column_id = referenced_column_id 
            AND col2.object_id =  tab2.object_id;
    

    【讨论】:

      【解决方案9】:

      在 SQL Server Management Studio 中,您只需右键单击 对象资源管理器并选择“查看依赖项”。这会给你一个 好的起点。它显示了引用的表、视图和过程 桌子。

      【讨论】:

        【解决方案10】:

        --以下内容可能会为您提供更多您正在寻找的内容:

        create Procedure spShowRelationShips 
        ( 
            @Table varchar(250) = null,
            @RelatedTable varchar(250) = null
        )
        as
        begin
            if @Table is null and @RelatedTable is null
                select  object_name(k.constraint_object_id) ForeginKeyName, 
                        object_name(k.Parent_Object_id) TableName, 
                        object_name(k.referenced_object_id) RelatedTable, 
                        c.Name RelatedColumnName,  
                        object_name(rc.object_id) + '.' + rc.name RelatedKeyField
                from sys.foreign_key_columns k
                left join sys.columns c on object_name(c.object_id) = object_name(k.Parent_Object_id) and c.column_id = k.parent_column_id
                left join sys.columns rc on object_name(rc.object_id) = object_name(k.referenced_object_id) and rc.column_id = k.referenced_column_id
                order by 2,3
        
            if @Table is not null and @RelatedTable is null
                select  object_name(k.constraint_object_id) ForeginKeyName, 
                        object_name(k.Parent_Object_id) TableName, 
                        object_name(k.referenced_object_id) RelatedTable, 
                        c.Name RelatedColumnName,  
                        object_name(rc.object_id) + '.' + rc.name RelatedKeyField
                from sys.foreign_key_columns k
                left join sys.columns c on object_name(c.object_id) = object_name(k.Parent_Object_id) and c.column_id = k.parent_column_id
                left join sys.columns rc on object_name(rc.object_id) = object_name(k.referenced_object_id) and rc.column_id = k.referenced_column_id
                where object_name(k.Parent_Object_id) =@Table
                order by 2,3
        
            if @Table is null and @RelatedTable is not null
                select  object_name(k.constraint_object_id) ForeginKeyName, 
                        object_name(k.Parent_Object_id) TableName, 
                        object_name(k.referenced_object_id) RelatedTable, 
                        c.Name RelatedColumnName,  
                        object_name(rc.object_id) + '.' + rc.name RelatedKeyField
                from sys.foreign_key_columns k
                left join sys.columns c on object_name(c.object_id) = object_name(k.Parent_Object_id) and c.column_id = k.parent_column_id
                left join sys.columns rc on object_name(rc.object_id) = object_name(k.referenced_object_id) and rc.column_id = k.referenced_column_id
                where object_name(k.referenced_object_id) =@RelatedTable
                order by 2,3
        
        
        
        end
        

        【讨论】:

          【解决方案11】:

          您还可以通过修改@LittleSweetSeas 答案返回有关Foreign Keys 的所有信息:

          SELECT 
             OBJECT_NAME(f.parent_object_id) ConsTable,
             OBJECT_NAME (f.referenced_object_id) refTable,
             COL_NAME(fc.parent_object_id,fc.parent_column_id) ColName
          FROM 
             sys.foreign_keys AS f
          INNER JOIN 
             sys.foreign_key_columns AS fc 
                ON f.OBJECT_ID = fc.constraint_object_id
          INNER JOIN 
             sys.tables t 
                ON t.OBJECT_ID = fc.referenced_object_id
          order by
          ConsTable
          

          【讨论】:

            【解决方案12】:

            在对象资源管理器中,展开表格,然后展开键:

            【讨论】:

              【解决方案13】:

              尝试以下查询。

              select object_name(sfc.constraint_object_id) AS constraint_name,
                     OBJECT_Name(parent_object_id) AS table_name ,
                     ac1.name as table_column_name,
                     OBJECT_name(referenced_object_id) as reference_table_name,      
                     ac2.name as reference_column_name
              from  sys.foreign_key_columns sfc
              join sys.all_columns ac1 on (ac1.object_id=sfc.parent_object_id and ac1.column_id=sfc.parent_column_id)
              join sys.all_columns ac2 on (ac2.object_id=sfc.referenced_object_id and ac2.column_id=sfc.referenced_column_id) 
              where sfc.parent_object_id=OBJECT_ID(<main table name>);
              

              这将给出约束名,列名将被引用,并且将取决于约束的表将在那里。

              【讨论】:

                【解决方案14】:

                您可以使用此查询来显示Foreign key 约束:

                SELECT
                K_Table = FK.TABLE_NAME,
                FK_Column = CU.COLUMN_NAME,
                PK_Table = PK.TABLE_NAME,
                PK_Column = PT.COLUMN_NAME,
                Constraint_Name = C.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
                INNER JOIN (
                SELECT 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
                WHERE i1.CONSTRAINT_TYPE = 'PRIMARY KEY'
                ) PT ON PT.TABLE_NAME = PK.TABLE_NAME
                ---- optional:
                ORDER BY
                1,2,3,4
                WHERE PK.TABLE_NAME='YourTable'
                

                取自http://blog.sqlauthority.com/2006/11/01/sql-server-query-to-display-foreign-key-relationships-and-name-of-the-constraint-for-each-table-in-database/

                【讨论】:

                  【解决方案15】:

                  获取表格的Primary KeyForeign Key 的最简单方法是:

                  /*  Get primary key and foreign key for a table */
                  USE DatabaseName;
                  
                  SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
                  WHERE CONSTRAINT_NAME LIKE 'PK%' AND
                  TABLE_NAME = 'TableName'
                  
                  SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
                  WHERE CONSTRAINT_NAME LIKE 'FK%' AND
                  TABLE_NAME = 'TableName'
                  

                  【讨论】:

                    【解决方案16】:

                    程序

                    sp_help 'tbl_name'

                    确实提供了很多信息,但我找到了程序

                    sp_fkeys 'tbl_name'sp_pkeys 'tbl_name'

                    更易于使用,并且可能具有更面向未来的结果。

                    (他们确实完美地回答了 OP)

                    【讨论】:

                      猜你喜欢
                      • 2014-03-20
                      • 1970-01-01
                      • 2019-10-05
                      • 1970-01-01
                      • 2018-08-08
                      • 1970-01-01
                      • 1970-01-01
                      • 2017-12-02
                      • 2023-03-22
                      相关资源
                      最近更新 更多