【问题标题】:How can I list all foreign keys referencing a given table in SQL Server?如何列出引用 SQL Server 中给定表的所有外键?
【发布时间】:2010-10-03 17:58:12
【问题描述】:

我需要删除 SQL Server 数据库中高度引用的表。如何获取我需要删除才能删除表的所有外键约束的列表?

(SQL 回答比在管理工作室的 GUI 中单击 about 更可取。)

【问题讨论】:

标签: sql sql-server tsql


【解决方案1】:

不知道为什么没有人建议,但我使用sp_fkeys 来查询给定表的外键:

EXEC sp_fkeys 'TableName'

您还可以指定架构:

EXEC sp_fkeys @pktable_name = 'TableName', @pktable_owner = 'dbo'

在不指定架构的情况下,docs 声明以下内容:

如果没有指定pktable_owner,默认的表可见性规则 的基础 DBMS 应用。

在 SQL Server 中,如果当前用户拥有一个具有指定 名称,则返回该表的列。如果 pktable_owner 不是 指定并且当前用户不拥有具有指定的表 pktable_name,该过程查找具有指定的表 pktable_name 由数据库所有者拥有。如果存在,则该表的 列被返回。

【讨论】:

  • 由于某种原因,这对我在 sql 2008 数据库上不起作用。 sp_help 显示关系,但此命令不会。
  • @tbone:我遇到了同样的问题,这与未完全指定参数有关。给定由 O 拥有的表 T,在数据库 D 中,您需要执行 EXEC sp_fkeys \@pktable_name='T', \@pktable_owner='O', \@pktable_qualifier='D' 尝试查看 EXEC sp_tables \@ 的输出table_name ='T' 找出参数值应该是什么。
  • @JustinRusso 您可以通过创建一个表来解决这个问题,将结果存储到表中,然后选择特定的列。查看this link 的示例:)。
  • 在 SSMS 2014 中运行良好。谢谢。
  • 上面的 cmets 已经回答过了:但只是为了清楚起见 - EXEC sp_fkeys @pktable_name = N'Department' ,@pktable_owner = N'dbo'; msdn.microsoft.com/en-NZ/library/ms175090.aspx
【解决方案2】:

我会使用 SQL Server Management Studio 中的数据库图表功能,但既然你排除了这一点 - 这在 SQL Server 2008 中对我有用(没有 2005)。

获取引用表和列名的列表...

select 
    t.name as TableWithForeignKey, 
    fk.constraint_column_id as FK_PartNo, c.
    name as ForeignKeyColumn 
from 
    sys.foreign_key_columns as fk
inner join 
    sys.tables as t on fk.parent_object_id = t.object_id
inner join 
    sys.columns as c on fk.parent_object_id = c.object_id and fk.parent_column_id = c.column_id
where 
    fk.referenced_object_id = (select object_id 
                               from sys.tables 
                               where name = 'TableOthersForeignKeyInto')
order by 
    TableWithForeignKey, FK_PartNo

获取外键约束的名称

select distinct name from sys.objects where object_id in 
(   select fk.constraint_object_id from sys.foreign_key_columns as fk
    where fk.referenced_object_id = 
        (select object_id from sys.tables where name = 'TableOthersForeignKeyInto')
)

【讨论】:

  • 很好,虽然使用了 referenced_object_id 而不是 parent。 select distinct name from sys.objects where object_id in ( select fk.constraint_object_id from sys.foreign_key_columns as fk where fk.referenced_object_id = (select object_id from sys.tables where name = 'tablename') )
  • 在第一个查询的select中加入“object_name(constraint_object_id)”可以得到FK的名字。
  • 可以获取对象id object_id('TableOthersForeignKeyInto')
【解决方案3】:

这给了你:

  • FK 本身
  • FK 所属的架构
  • 引用表”或具有 FK 的表
  • 引用列”或引用表中指向 FK 的列
  • 引用表”或具有 FK 指向的键列的表
  • 引用的列”或作为 FK 指向的键的列

代码如下:

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

【讨论】:

  • 如果您想在之后过滤结果,这是我认为的最佳答案。
  • 效果很好!如果您:a)在所有列名前加上“Fk”/“Key”,b)在所有列名后加上“Name”,c)删除下划线,d)添加 KeyTableSchemaName,e)添加默认值会更好order by:KeyTableSchemaName、KeyTableName、KeyColumnName、FkTableSchemaName、FkTableName、FkName 和 f) 将列顺序更改为:KeyTableSchemaName、KeyTableName、KeyColumnName、FkTableSchemaName、FkTableName、FkName、FkColumnName、a/b/c/d 以保持一致性/最常见最可能使用的最佳实践命名约定和 d/e(列出 Table 的 FK 依赖项)。
  • 这样一个很好的答案和有用的查询。谢谢
  • 如果您没有任何多列外键,此查询效果最佳。
  • 这应该是公认的答案,并非所有 FK 场景都包含在其他答案中
【解决方案4】:

试试这个:

sp_help 'TableName'

【讨论】:

  • 了解您是否手动探索数据库的好帮手方法。此外,它适用于 Azure SQL Server。
【解决方案5】:

您还应该注意对其他对象的引用。

如果该表被其他表高度引用,则它可能也被其他对象(例如视图、存储过程、函数等)高度引用。

我真的会推荐 GUI 工具,例如 SSMS 中的“查看依赖项”对话框或免费工具,例如 ApexSQL Search,因为如果您只想使用 SQL 来搜索其他对象中的依赖项,可能会出错。

如果 SQL 是唯一的选择,您可以尝试这样做。

select O.name as [Object_Name], C.text as [Object_Definition]
from sys.syscomments C
inner join sys.all_objects O ON C.id = O.object_id
where C.text like '%table_name%'

【讨论】:

    【解决方案6】:

    最初的问题要求将所有外键的列表放入一个高度引用的表中,以便可以删除该表。

    这个小查询返回将所有外键删除到特定表中所需的所有“删除外键”命令:

    SELECT 
       'ALTER TABLE ['+sch.name+'].['+referencingTable.Name+'] DROP CONSTRAINT ['+foreignKey.name+']' '[DropCommand]'
    FROM sys.foreign_key_columns fk
        JOIN sys.tables referencingTable ON fk.parent_object_id = referencingTable.object_id
        JOIN sys.schemas sch ON referencingTable.schema_id = sch.schema_id
        JOIN sys.objects foreignKey ON foreignKey.object_id = fk.constraint_object_id
        JOIN sys.tables referencedTable ON fk.referenced_object_id = referencedTable.object_id
    WHERE referencedTable.name = 'MyTableName'
    

    示例输出:

    [DropCommand]
    ALTER TABLE [dbo].[OtherTable1] DROP CONSTRAINT [FK_OtherTable1_MyTable]
    ALTER TABLE [dbo].[OtherTable2] DROP CONSTRAINT [FK_OtherTable2_MyTable]
    

    省略 WHERE 子句以获取当前数据库中所有外键的删除命令。

    【讨论】:

      【解决方案7】:

      这是我将使用的 SQL 代码。

      SELECT 
         f.name AS 'Name of Foreign Key',
         OBJECT_NAME(f.parent_object_id) AS 'Table name',
         COL_NAME(fc.parent_object_id,fc.parent_column_id) AS 'Fieldname',
         OBJECT_NAME(t.object_id) AS 'References Table name',
         COL_NAME(t.object_id,fc.referenced_column_id) AS 'References fieldname',
      
         'ALTER TABLE [' + OBJECT_NAME(f.parent_object_id) + ']  DROP CONSTRAINT [' + f.name + ']' AS 'Delete foreign key',
      
         'ALTER TABLE [' + OBJECT_NAME(f.parent_object_id) + ']  WITH NOCHECK ADD CONSTRAINT [' + 
              f.name + '] FOREIGN KEY([' + COL_NAME(fc.parent_object_id,fc.parent_column_id) + ']) REFERENCES ' + 
              '[' + OBJECT_NAME(t.object_id) + '] ([' +
              COL_NAME(t.object_id,fc.referenced_column_id) + '])' AS 'Create foreign key'
          -- , delete_referential_action_desc AS 'UsesCascadeDelete'
      FROM sys.foreign_keys AS f,
           sys.foreign_key_columns AS fc,
           sys.tables t 
      WHERE f.OBJECT_ID = fc.constraint_object_id
      AND t.OBJECT_ID = fc.referenced_object_id
      AND OBJECT_NAME(t.object_id) = 'Employees'      --  Just show the FKs which reference a particular table
      ORDER BY 2
      

      SQL不是特别清楚,我们来看一个例子。

      所以,假设我想删除 Microsoft 钟爱的 Northwind 数据库中的 Employees 表,但 SQL Server 告诉我有一个或多个外键阻止我这样做。

      上面的 SQL 命令会返回这些结果...

      它显示有 3 个外键引用 Employees 表。换句话说,在这三个外键首先被删除之前,我不会被允许删除(删除)这个表。

      在结果中,第一行是以下外键约束在结果中的显示方式。

      ALTER TABLE [dbo].[Employees]  WITH NOCHECK 
      ADD CONSTRAINT [FK_Employees_Employees] FOREIGN KEY([ReportsTo])
      REFERENCES [dbo].[Employees] ([EmployeeID])
      

      倒数第二列显示了我需要用来删除这些外键之一的 SQL 命令,例如:

      ALTER TABLE [Employees] DROP CONSTRAINT [FK_Employees_Employees]
      

      ...右侧的列显示用于创建它的 SQL...

      ALTER TABLE [Employees] WITH NOCHECK 
      ADD CONSTRAINT [FK_Employees_Employees] 
      FOREIGN KEY([ReportsTo]) REFERENCES [Employees] ([EmployeeID])
      

      使用所有这些命令,您拥有删除相关外键所需的一切,以便您删除表,然后再重新创建它们。

      呸。希望这会有所帮助。

      【讨论】:

      • 如果您使用内部连接和 on 子句而不是交叉连接会更清楚。但这仍然很有帮助!
      【解决方案8】:

      最简单的方法是在 SQL 中使用 sys.foreign_keys_columns。在这里,该表包含所有外键的对象 ID,包括它们的引用列 ID 引用表 ID 以及引用列和表。由于 Id 保持不变,因此结果对于 Schema 和表中的进一步修改将是可靠的。

      查询:

      SELECT    
      OBJECT_NAME(fkeys.constraint_object_id) foreign_key_name
      ,OBJECT_NAME(fkeys.parent_object_id) referencing_table_name
      ,COL_NAME(fkeys.parent_object_id, fkeys.parent_column_id) referencing_column_name
      ,OBJECT_SCHEMA_NAME(fkeys.parent_object_id) referencing_schema_name
      ,OBJECT_NAME (fkeys.referenced_object_id) referenced_table_name
      ,COL_NAME(fkeys.referenced_object_id, fkeys.referenced_column_id) 
      referenced_column_name
      ,OBJECT_SCHEMA_NAME(fkeys.referenced_object_id) referenced_schema_name
      FROM sys.foreign_key_columns AS fkeys
      

      我们也可以使用'where'来添加过滤器

      WHERE OBJECT_NAME(fkeys.parent_object_id) = 'table_name' AND 
      OBJECT_SCHEMA_NAME(fkeys.parent_object_id) = 'schema_name'
      

      【讨论】:

      • 当您需要删除整个数据库结构/引用表集时,这非常适合。
      【解决方案9】:
      SELECT PKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()),
             PKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O1.SCHEMA_ID)),
             PKTABLE_NAME = CONVERT(SYSNAME,O1.NAME),
             PKCOLUMN_NAME = CONVERT(SYSNAME,C1.NAME),
             FKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()),
             FKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O2.SCHEMA_ID)),
             FKTABLE_NAME = CONVERT(SYSNAME,O2.NAME),
             FKCOLUMN_NAME = CONVERT(SYSNAME,C2.NAME),
             -- Force the column to be non-nullable (see SQL BU 325751)
             --KEY_SEQ             = isnull(convert(smallint,k.constraint_column_id), sysconv(smallint,0)),
             UPDATE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.OBJECT_ID,'CnstIsUpdateCascade') 
                                              WHEN 1 THEN 0
                                              ELSE 1
                                            END),
             DELETE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.OBJECT_ID,'CnstIsDeleteCascade') 
                                              WHEN 1 THEN 0
                                              ELSE 1
                                            END),
             FK_NAME = CONVERT(SYSNAME,OBJECT_NAME(F.OBJECT_ID)),
             PK_NAME = CONVERT(SYSNAME,I.NAME),
             DEFERRABILITY = CONVERT(SMALLINT,7)   -- SQL_NOT_DEFERRABLE
      FROM   SYS.ALL_OBJECTS O1,
             SYS.ALL_OBJECTS O2,
             SYS.ALL_COLUMNS C1,
             SYS.ALL_COLUMNS C2,
             SYS.FOREIGN_KEYS F
             INNER JOIN SYS.FOREIGN_KEY_COLUMNS K
               ON (K.CONSTRAINT_OBJECT_ID = F.OBJECT_ID)
             INNER JOIN SYS.INDEXES I
               ON (F.REFERENCED_OBJECT_ID = I.OBJECT_ID
                   AND F.KEY_INDEX_ID = I.INDEX_ID)
      WHERE  O1.OBJECT_ID = F.REFERENCED_OBJECT_ID
             AND O2.OBJECT_ID = F.PARENT_OBJECT_ID
             AND C1.OBJECT_ID = F.REFERENCED_OBJECT_ID
             AND C2.OBJECT_ID = F.PARENT_OBJECT_ID
             AND C1.COLUMN_ID = K.REFERENCED_COLUMN_ID
             AND C2.COLUMN_ID = K.PARENT_COLUMN_ID
      

      【讨论】:

        【解决方案10】:
        SELECT
          object_name(parent_object_id),
          object_name(referenced_object_id),
          name 
        FROM sys.foreign_keys
        WHERE parent_object_id = object_id('Table Name')
        

        【讨论】:

          【解决方案11】:

          我正在使用此脚本来查找与外键相关的所有详细信息。 我正在使用 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
          

          【讨论】:

            【解决方案12】:

            引用 SQL Server 中给定表的所有外键列表:

            您可以通过以下查询获得引用的表名和列名...

            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) = 'TableName'
            

            以下截图供您理解...

            【讨论】:

              【解决方案13】:

              第一

              EXEC sp_fkeys 'Table', 'Schema'
              

              然后使用NimbleText 来玩弄你的结果

              【讨论】:

                【解决方案14】:

                上面有一些很好的答案。但我更喜欢通过 one 查询获得答案。 这段代码取自 sys.sp_helpconstraint(sys proc)

                如果存在与 tbl 关联的外键,Microsoft 会采用这种方式进行查找。

                --setup variables. Just change 'Customer' to tbl you want
                declare @objid int,
                    @objname nvarchar(776)
                select @objname = 'Customer'    
                select @objid = object_id(@objname)
                
                if exists (select * from sys.foreign_keys where referenced_object_id = @objid)
                    select 'Table is referenced by foreign key' =
                        db_name() + '.'
                        + rtrim(schema_name(ObjectProperty(parent_object_id,'schemaid')))
                        + '.' + object_name(parent_object_id)
                        + ': ' + object_name(object_id)
                    from sys.foreign_keys 
                    where referenced_object_id = @objid 
                    order by 1
                

                答案将如下所示:test_db_name.dbo.Account: FK_Account_Customer

                【讨论】:

                • 这实际上就像 4 个单独的查询语句......这在一个语句中实际上做了同样的事情:select db_name() + '.' + schema_name(ObjectProperty(parent_object_id,'schemaid')) + '.' + object_name(parent_object_id) + ': ' + object_name(object_id) AS "FK Reference" from sys.foreign_keys where referenced_object_id = object_id('Customer')
                【解决方案15】:
                 SELECT OBJECT_NAME(fk.parent_object_id) as ReferencingTable, 
                        OBJECT_NAME(fk.constraint_object_id) as [FKContraint]
                  FROM sys.foreign_key_columns as fk
                 WHERE fk.referenced_object_id = OBJECT_ID('ReferencedTable', 'U')
                

                这仅显示外键约束时的关系。我的数据库显然早于 FK 约束。一些表使用触发器来强制执行引用完整性,有时只有一个类似命名的列来指示关系(并且根本没有引用完整性)。

                幸运的是,我们确实有一个一致的命名场景,所以我能够找到引用表 和这样的观点:

                SELECT OBJECT_NAME(object_id) from sys.columns where name like 'client_id'
                

                我使用此选择作为生成脚本的基础,该脚本执行我需要执行的操作 相关表格。

                【讨论】:

                  【解决方案16】:
                  SELECT
                  OBJECT_NAME(parent_object_id) 'Parent table',
                  c.NAME 'Parent column name',
                  OBJECT_NAME(referenced_object_id) 'Referenced table',
                  cref.NAME 'Referenced column name'
                  FROM 
                  sys.foreign_key_columns fkc 
                  INNER JOIN 
                  sys.columns c 
                     ON fkc.parent_column_id = c.column_id 
                        AND fkc.parent_object_id = c.object_id
                  INNER JOIN 
                  sys.columns cref 
                     ON fkc.referenced_column_id = cref.column_id 
                        AND fkc.referenced_object_id = cref.object_id  where   OBJECT_NAME(parent_object_id) = 'tablename'
                  

                  如果你想得到所有表的外键关系排除where子句,否则写你的表名而不是tablename

                  【讨论】:

                    【解决方案17】:

                    Mysql 服务器有information_schema.REFERENTIAL_CONSTRAINTS 表仅供参考,您可以通过表名或引用的表名对其进行过滤。

                    【讨论】:

                      【解决方案18】:

                      @BankZ 的最佳答案

                      sp_help 'TableName'   
                      

                      另外用于不同的架构

                      sp_help 'schemaName.TableName'   
                      

                      【讨论】:

                      • 谢谢。 sp_help 'TableName' 为我工作。
                      【解决方案19】:

                      利用@Gishu 所做的工作,我能够在 SQL Server 2005 中生成和使用以下 SQL

                      SELECT t.name AS TableWithForeignKey, fk.constraint_column_id AS FK_PartNo, 
                             c.name AS ForeignKeyColumn, o.name AS FK_Name 
                        FROM sys.foreign_key_columns AS fk
                             INNER JOIN sys.tables AS t ON fk.parent_object_id = t.object_id
                             INNER JOIN sys.columns AS c ON fk.parent_object_id = c.object_id 
                                                        AND fk.parent_column_id = c.column_id
                             INNER JOIN sys.objects AS o ON fk.constraint_object_id = o.object_id
                        WHERE fk.referenced_object_id = (SELECT object_id FROM sys.tables 
                                                              WHERE name = 'TableOthersForeignKeyInto')
                        ORDER BY TableWithForeignKey, FK_PartNo;
                      

                      在 1 个查询中显示所有表、列和外键名称。

                      【讨论】:

                        【解决方案20】:

                        确定数据库中所有表的主键和唯一键...

                        这应该列出所有的约束,最后你可以放置你的过滤器

                        /* CAST IS DONE , SO THAT OUTPUT INTEXT FILE REMAINS WITH SCREEN LIMIT*/
                        WITH   ALL_KEYS_IN_TABLE (CONSTRAINT_NAME,CONSTRAINT_TYPE,PARENT_TABLE_NAME,PARENT_COL_NAME,PARENT_COL_NAME_DATA_TYPE,REFERENCE_TABLE_NAME,REFERENCE_COL_NAME) 
                        AS
                        (
                        SELECT  CONSTRAINT_NAME= CAST (PKnUKEY.name AS VARCHAR(30)) ,
                                CONSTRAINT_TYPE=CAST (PKnUKEY.type_desc AS VARCHAR(30)) ,
                                PARENT_TABLE_NAME=CAST (PKnUTable.name AS VARCHAR(30)) ,
                                PARENT_COL_NAME=CAST ( PKnUKEYCol.name AS VARCHAR(30)) ,
                                PARENT_COL_NAME_DATA_TYPE=  oParentColDtl.DATA_TYPE,        
                                REFERENCE_TABLE_NAME='' ,
                                REFERENCE_COL_NAME='' 
                        
                        FROM sys.key_constraints as PKnUKEY
                            INNER JOIN sys.tables as PKnUTable
                                    ON PKnUTable.object_id = PKnUKEY.parent_object_id
                            INNER JOIN sys.index_columns as PKnUColIdx
                                    ON PKnUColIdx.object_id = PKnUTable.object_id
                                    AND PKnUColIdx.index_id = PKnUKEY.unique_index_id
                            INNER JOIN sys.columns as PKnUKEYCol
                                    ON PKnUKEYCol.object_id = PKnUTable.object_id
                                    AND PKnUKEYCol.column_id = PKnUColIdx.column_id
                             INNER JOIN INFORMATION_SCHEMA.COLUMNS oParentColDtl
                                    ON oParentColDtl.TABLE_NAME=PKnUTable.name
                                    AND oParentColDtl.COLUMN_NAME=PKnUKEYCol.name
                        UNION ALL
                        SELECT  CONSTRAINT_NAME= CAST (oConstraint.name AS VARCHAR(30)) ,
                                CONSTRAINT_TYPE='FK',
                                PARENT_TABLE_NAME=CAST (oParent.name AS VARCHAR(30)) ,
                                PARENT_COL_NAME=CAST ( oParentCol.name AS VARCHAR(30)) ,
                                PARENT_COL_NAME_DATA_TYPE= oParentColDtl.DATA_TYPE,     
                                REFERENCE_TABLE_NAME=CAST ( oReference.name AS VARCHAR(30)) ,
                                REFERENCE_COL_NAME=CAST (oReferenceCol.name AS VARCHAR(30)) 
                        FROM sys.foreign_key_columns FKC
                            INNER JOIN sys.sysobjects oConstraint
                                    ON FKC.constraint_object_id=oConstraint.id 
                            INNER JOIN sys.sysobjects oParent
                                    ON FKC.parent_object_id=oParent.id
                            INNER JOIN sys.all_columns oParentCol
                                    ON FKC.parent_object_id=oParentCol.object_id /* ID of the object to which this column belongs.*/
                                    AND FKC.parent_column_id=oParentCol.column_id/* ID of the column. Is unique within the object.Column IDs might not be sequential.*/
                            INNER JOIN sys.sysobjects oReference
                                    ON FKC.referenced_object_id=oReference.id
                            INNER JOIN INFORMATION_SCHEMA.COLUMNS oParentColDtl
                                    ON oParentColDtl.TABLE_NAME=oParent.name
                                    AND oParentColDtl.COLUMN_NAME=oParentCol.name
                            INNER JOIN sys.all_columns oReferenceCol
                                    ON FKC.referenced_object_id=oReferenceCol.object_id /* ID of the object to which this column belongs.*/
                                    AND FKC.referenced_column_id=oReferenceCol.column_id/* ID of the column. Is unique within the object.Column IDs might not be sequential.*/
                        
                        )
                        
                        select * from   ALL_KEYS_IN_TABLE
                        where   
                            PARENT_TABLE_NAME  in ('YOUR_TABLE_NAME') 
                            or REFERENCE_TABLE_NAME  in ('YOUR_TABLE_NAME')
                        ORDER BY PARENT_TABLE_NAME,CONSTRAINT_NAME;
                        

                        供参考,请阅读-http://blogs.msdn.com/b/sqltips/archive/2005/09/16/469136.aspx

                        【讨论】:

                        • 对于所提出的问题,这包含太多信息。你能否包括一些解释(并删除额外的代码)来回答这个问题,好吗?您发布了对两个不同问题的确切答案,每个问题只需要此答案的部分
                        • 我编辑了答案 - 确定数据库中所有表的主键和唯一键...我认为这里的答案是合适的,因为问题适用于所有参考。
                        【解决方案21】:

                        我在 2008 年及以后一直在使用它。它与列出的其他一些解决方案类似,但字段名称是正确大小写的以处理特定于大小写的 (LatBin) 排序规则。此外,您可以为其提供一个表名并仅检索该表的信息。

                        -->>SPECIFY THE DESIRED DB
                        USE ???
                        GO
                        
                        /*********************************************************************************************
                        
                            LIST OUT ALL PRIMARY AND FOREIGN KEY CONSTRAINTS IN A DB OR FOR A SPECIFIED TABLE
                        
                        *********************************************************************************************/
                        DECLARE @tblName VARCHAR(255) 
                        
                        /*******************/
                        
                            SET @tblName = NULL-->NULL will return all PK/FK constraints for every table in the database
                        
                        /*******************/
                        
                        SELECT PKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()), 
                               PKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O1.schema_id)), 
                               PKTABLE_NAME = CONVERT(SYSNAME,O1.name), 
                               PKCOLUMN_NAME = CONVERT(SYSNAME,C1.name), 
                               FKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()), 
                               FKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O2.schema_id)), 
                               FKTABLE_NAME = CONVERT(SYSNAME,O2.name), 
                               FKCOLUMN_NAME = CONVERT(SYSNAME,C2.name), 
                               -- Force the column to be non-nullable (see SQL BU 325751) 
                               KEY_SEQ             = isnull(convert(smallint,K.constraint_column_id),0), 
                               UPDATE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.object_id,'CnstIsUpdateCascade')  
                                                                WHEN 1 THEN 0 
                                                                ELSE 1 
                                                              END), 
                               DELETE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.object_id,'CnstIsDeleteCascade')  
                                                                WHEN 1 THEN 0 
                                                                ELSE 1 
                                                              END), 
                               FK_NAME = CONVERT(SYSNAME,OBJECT_NAME(F.object_id)), 
                               PK_NAME = CONVERT(SYSNAME,I.name), 
                               DEFERRABILITY = CONVERT(SMALLINT,7)   -- SQL_NOT_DEFERRABLE 
                        FROM   sys.all_objects O1, 
                               sys.all_objects O2, 
                               sys.all_columns C1, 
                               sys.all_columns C2, 
                               sys.foreign_keys F 
                               INNER JOIN sys.foreign_key_columns K 
                                 ON (K.constraint_object_id = F.object_id) 
                               INNER JOIN sys.indexes I 
                                 ON (F.referenced_object_id = I.object_id 
                                     AND F.key_index_id = I.index_id) 
                        WHERE  O1.object_id = F.referenced_object_id 
                               AND O2.object_id = F.parent_object_id 
                               AND C1.object_id = F.referenced_object_id 
                               AND C2.object_id = F.parent_object_id 
                               AND C1.column_id = K.referenced_column_id
                               AND C2.column_id = K.parent_column_id
                               AND (   O1.name = @tblName 
                                    OR O2.name = @tblName
                                    OR @tblName IS null)
                        ORDER BY PKTABLE_NAME,FKTABLE_NAME
                        

                        【讨论】:

                          【解决方案22】:

                          这将获取涉及所选表的任何外键。 *假定为 _FIRSTABLENAME_SECONDTABLENAME 格式。

                           declare @tablename as varchar(MAX)
                           SET @tablename = 'yourtablename'
                           SELECT name
                           FROM YOURDATABASE.sys.objects
                           WHERE type_desc = 'FOREIGN_KEY_CONSTRAINT' and (name LIKE '%_' + @tablename + 'empdb_%' or name LIKE '%_' + @tablename )
                          

                          这是一种更通用的形式:

                           SELECT name
                           FROM YOURDATABASE_PROD.sys.objects
                           WHERE type_desc = 'FOREIGN_KEY_CONSTRAINT' and name LIKE '%' + @tablename + '%' and
                           name NOT LIKE '[a-zA-Z0-9]' + @tablename + '%' and name NOT LIKE '%' + @tablename + '[a-zA-Z0-9]' 
                          

                          【讨论】:

                            【解决方案23】:

                            这里有如何计算所选 ID 的所有责任。只需更改@dbTableName 值、@dbRowId 值及其类型(如果是 int,则需要删除第 82 行中的 '' (..SET @SQL = ..))。享受吧。

                            DECLARE @dbTableName varchar(max) = 'User'
                            DECLARE @dbRowId uniqueidentifier = '21d34ecd-c1fd-11e2-8545-002219a42e1c'
                            
                            DECLARE @FK_ROWCOUNT int
                            DECLARE @SQL nvarchar(max)
                            
                            DECLARE @PKTABLE_QUALIFIER sysname
                            DECLARE @PKTABLE_OWNER sysname
                            DECLARE @PKTABLE_NAME sysname
                            DECLARE @PKCOLUMN_NAME sysname
                            DECLARE @FKTABLE_QUALIFIER sysname
                            DECLARE @FKTABLE_OWNER sysname
                            DECLARE @FKTABLE_NAME sysname
                            DECLARE @FKCOLUMN_NAME sysname
                            DECLARE @UPDATE_RULE smallint
                            DECLARE @DELETE_RULE smallint
                            DECLARE @FK_NAME sysname
                            DECLARE @PK_NAME sysname
                            DECLARE @DEFERRABILITY sysname
                            
                            IF OBJECT_ID('tempdb..#Temp1') IS NOT NULL
                                DROP TABLE #Temp1;
                            CREATE TABLE #Temp1 ( 
                                PKTABLE_QUALIFIER sysname,
                                PKTABLE_OWNER sysname,
                                PKTABLE_NAME sysname,
                                PKCOLUMN_NAME sysname,
                                FKTABLE_QUALIFIER sysname,
                                FKTABLE_OWNER sysname,
                                FKTABLE_NAME sysname,
                                FKCOLUMN_NAME sysname,
                                UPDATE_RULE smallint,
                                DELETE_RULE smallint,
                                FK_NAME sysname,
                                PK_NAME sysname,
                                DEFERRABILITY sysname,
                                FK_ROWCOUNT int
                                );
                            DECLARE FK_Counter_Cursor CURSOR FOR
                                SELECT PKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()),
                                   PKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O1.SCHEMA_ID)),
                                   PKTABLE_NAME = CONVERT(SYSNAME,O1.NAME),
                                   PKCOLUMN_NAME = CONVERT(SYSNAME,C1.NAME),
                                   FKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()),
                                   FKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O2.SCHEMA_ID)),
                                   FKTABLE_NAME = CONVERT(SYSNAME,O2.NAME),
                                   FKCOLUMN_NAME = CONVERT(SYSNAME,C2.NAME),
                                   -- Force the column to be non-nullable (see SQL BU 325751)
                                   --KEY_SEQ             = isnull(convert(smallint,k.constraint_column_id), sysconv(smallint,0)),
                                   UPDATE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.OBJECT_ID,'CnstIsUpdateCascade') 
                                                                    WHEN 1 THEN 0
                                                                    ELSE 1
                                                                  END),
                                   DELETE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.OBJECT_ID,'CnstIsDeleteCascade') 
                                                                    WHEN 1 THEN 0
                                                                    ELSE 1
                                                                  END),
                                   FK_NAME = CONVERT(SYSNAME,OBJECT_NAME(F.OBJECT_ID)),
                                   PK_NAME = CONVERT(SYSNAME,I.NAME),
                                   DEFERRABILITY = CONVERT(SMALLINT,7)   -- SQL_NOT_DEFERRABLE
                                FROM   SYS.ALL_OBJECTS O1,
                                       SYS.ALL_OBJECTS O2,
                                       SYS.ALL_COLUMNS C1,
                                       SYS.ALL_COLUMNS C2,
                                       SYS.FOREIGN_KEYS F
                                       INNER JOIN SYS.FOREIGN_KEY_COLUMNS K
                                         ON (K.CONSTRAINT_OBJECT_ID = F.OBJECT_ID)
                                       INNER JOIN SYS.INDEXES I
                                         ON (F.REFERENCED_OBJECT_ID = I.OBJECT_ID
                                             AND F.KEY_INDEX_ID = I.INDEX_ID)
                                WHERE  O1.OBJECT_ID = F.REFERENCED_OBJECT_ID
                                       AND O2.OBJECT_ID = F.PARENT_OBJECT_ID
                                       AND C1.OBJECT_ID = F.REFERENCED_OBJECT_ID
                                       AND C2.OBJECT_ID = F.PARENT_OBJECT_ID
                                       AND C1.COLUMN_ID = K.REFERENCED_COLUMN_ID
                                       AND C2.COLUMN_ID = K.PARENT_COLUMN_ID
                                       AND O1.NAME = @dbTableName
                            OPEN FK_Counter_Cursor;
                            FETCH NEXT FROM FK_Counter_Cursor INTO @PKTABLE_QUALIFIER, @PKTABLE_OWNER, @PKTABLE_NAME, @PKCOLUMN_NAME, @FKTABLE_QUALIFIER, @FKTABLE_OWNER, @FKTABLE_NAME, @FKCOLUMN_NAME, @UPDATE_RULE, @DELETE_RULE, @FK_NAME, @PK_NAME, @DEFERRABILITY;
                            WHILE @@FETCH_STATUS = 0
                               BEGIN
                                    SET @SQL = 'SELECT @dbCountOut = COUNT(*) FROM [' + @FKTABLE_NAME + '] WHERE [' + @FKCOLUMN_NAME + '] = ''' + CAST(@dbRowId AS varchar(max)) + '''';
                                    EXECUTE sp_executesql @SQL, N'@dbCountOut int OUTPUT', @dbCountOut = @FK_ROWCOUNT OUTPUT;
                                    INSERT INTO #Temp1 (PKTABLE_QUALIFIER, PKTABLE_OWNER, PKTABLE_NAME, PKCOLUMN_NAME, FKTABLE_QUALIFIER, FKTABLE_OWNER, FKTABLE_NAME, FKCOLUMN_NAME, UPDATE_RULE, DELETE_RULE, FK_NAME, PK_NAME, DEFERRABILITY, FK_ROWCOUNT) VALUES (@FKTABLE_QUALIFIER, @PKTABLE_OWNER, @PKTABLE_NAME, @PKCOLUMN_NAME, @FKTABLE_QUALIFIER, @FKTABLE_OWNER, @FKTABLE_NAME, @FKCOLUMN_NAME, @UPDATE_RULE, @DELETE_RULE, @FK_NAME, @PK_NAME, @DEFERRABILITY, @FK_ROWCOUNT)
                                  FETCH NEXT FROM FK_Counter_Cursor INTO @PKTABLE_QUALIFIER, @PKTABLE_OWNER, @PKTABLE_NAME, @PKCOLUMN_NAME, @FKTABLE_QUALIFIER, @FKTABLE_OWNER, @FKTABLE_NAME, @FKCOLUMN_NAME, @UPDATE_RULE, @DELETE_RULE, @FK_NAME, @PK_NAME, @DEFERRABILITY;
                               END;
                            CLOSE FK_Counter_Cursor;
                            DEALLOCATE FK_Counter_Cursor;
                            GO
                            SELECT * FROM #Temp1
                            GO
                            

                            【讨论】:

                              【解决方案24】:

                              以下解决方案对我有用:

                              --Eliminar las llaves foraneas
                              declare @query varchar(8000)
                              declare cursorRecorrerTabla cursor for
                              
                              SELECT  'ALTER TABLE [PoaComFinH].['+sch.name+'].['+referencingTable.Name+'] DROP CONSTRAINT ['+foreignKey.name+']' 'query'
                              FROM PoaComFinH.sys.foreign_key_columns fk
                              JOIN PoaComFinH.sys.tables referencingTable ON fk.parent_object_id = referencingTable.object_id
                              JOIN PoaComFinH.sys.schemas sch ON referencingTable.schema_id = sch.schema_id
                              JOIN PoaComFinH.sys.objects foreignKey ON foreignKey.object_id = fk.constraint_object_id
                              JOIN PoaComFinH.sys.tables referencedTable ON fk.referenced_object_id = referencedTable.object_id
                              
                              
                              --3ro. abrir el cursor.
                              open cursorRecorrerTabla
                              fetch next from cursorRecorrerTabla
                              into @query
                              while @@fetch_status = 0
                              begin
                              --inicio cuerpo del cursor
                                  print @query
                                  exec(@query)
                              --fin cuerpo del cursor
                              fetch next from cursorRecorrerTabla
                              into @query
                              end
                              --cerrar cursor
                              close cursorRecorrerTabla
                              deallocate cursorRecorrerTabla
                              

                              【讨论】:

                                【解决方案25】:

                                您可以通过以下查询找到:

                                 SELECT OBJECT_NAME (FK.referenced_object_id) 'Referenced Table', 
                                      OBJECT_NAME(FK.parent_object_id) 'Referring Table', FK.name 'Foreign Key', 
                                      COL_NAME(FK.referenced_object_id, FKC.referenced_column_id) 'Referenced Column',
                                      COL_NAME(FK.parent_object_id,FKC.parent_column_id) 'Referring Column'
                                     FROM sys.foreign_keys AS FK
                                             INNER JOIN sys.foreign_key_columns AS FKC 
                                                 ON FKC.constraint_object_id = FK.OBJECT_ID
                                     WHERE OBJECT_NAME (FK.referenced_object_id) = 'YourTableName'
                                     AND COL_NAME(FK.referenced_object_id, FKC.referenced_column_id) = 'YourColumnName'
                                     order by  OBJECT_NAME(FK.parent_object_id)
                                

                                【讨论】:

                                  【解决方案26】:

                                  也试试。

                                  EXEC sp_fkeys 'tableName', 'schemaName'
                                  

                                  使用sp_fkeys,您不仅可以使用 pk 表名和架构过滤结果,还可以使用 fk 表名和架构过滤结果。 link

                                  【讨论】:

                                    【解决方案27】:
                                    with tab_list as (
                                        select t.name AS Table_Name, t.object_id, s.name AS Table_Schema  from sys.tables t, sys.schemas s 
                                         where t.schema_id = s.schema_id
                                           and s.name = 'your schema') 
                                    select IIF(col.column_id = 1, tab.TABLE_SCHEMA + '.' + tab.TABLE_NAME, NULL) Table_Name,
                                           col.Name AS Column_Name, IIF(col.IS_NULLABLE= 0, 'NOT NULL', '') Nullable, st.name Type,
                                           CASE WHEN st.name = 'decimal' THEN CONVERT(NVARCHAR(4000), col.Precision) + ',' + CONVERT(NVARCHAR(4000), col.Scale) 
                                                WHEN col.max_length = -1 THEN 'max'
                                                WHEN st.name in ('int', 'bit', 'bigint', 'datetime2') THEN NULL
                                           ELSE CONVERT(NVARCHAR(4000), col.max_length / 2)
                                           END
                                           AS Length,
                                           ss.name + '.' + stab.name Referenced_Table, scol.name Referenced_Column 
                                    from sys.COLUMNS col  
                                        INNER JOIN tab_list tab ON col.object_id = tab.object_id
                                        INNER JOIN sys.types st ON col.system_type_id = st.system_type_id AND col.user_type_id = st.user_type_id 
                                        LEFT JOIN [sys].[foreign_key_columns] sfkc ON col.object_id = sfkc.parent_object_id AND col.column_id = sfkc.parent_column_id
                                        LEFT JOIN sys.tables stab ON sfkc.referenced_object_id = stab.object_id
                                        LEFT JOIN sys.columns scol ON sfkc.referenced_object_id = scol.object_id AND sfkc.referenced_column_id = scol.column_id 
                                        LEFT JOIN sys.schemas ss ON ss.schema_id = stab.schema_id
                                    

                                    【讨论】:

                                    • 这是一个非常庞大且多汁的 SQL。您能否解释一下它是如何工作的,以便我们能够从中学习?
                                    • 感谢@Simas JoneLiunas 编辑我凌乱的文本。我正在做迁移项目,需要列出所有列的信息,包括关系(FK)。该脚本将向您显示有关架构级别的信息。为您的特定目的在 tab_list 视图中进行更多修改。如果我早点知道对象 id 的内置函数会更简单:(.
                                    【解决方案28】:

                                    此答案构建 on,但格式类似于 sp_fkeys,适用于多个列并列出它们的顺序。

                                    SELECT fk_obj.name    AS FK_NAME,
                                           pk_schema.name AS PKTABLE_OWNER,
                                           pk_table.name  AS PKTABLE_NAME,
                                           pk_column.name AS PKCOLUMN_NAME,
                                           fk_schema.name AS FKTABLE_OWNER,
                                           fk_table.name  AS FKTABLE_NAME,
                                           fk_column.name AS FKCOLUMN_NAME,
                                           ROW_NUMBER() over (
                                               PARTITION BY fk_obj.name, fk_schema.name
                                               ORDER BY fkc.constraint_column_id
                                               )          AS KEY_SEQ
                                    FROM sys.foreign_key_columns fkc
                                             INNER JOIN sys.objects fk_obj
                                                        ON fk_obj.object_id = fkc.constraint_object_id
                                             INNER JOIN sys.tables fk_table
                                                        ON fk_table.object_id = fkc.parent_object_id
                                             INNER JOIN sys.schemas fk_schema
                                                        ON fk_table.schema_id = fk_schema.schema_id
                                             INNER JOIN sys.columns fk_column
                                                        ON fk_column.column_id = parent_column_id
                                                            AND fk_column.object_id = fk_table.object_id
                                             INNER JOIN sys.tables pk_table
                                                        ON pk_table.object_id = fkc.referenced_object_id
                                             INNER JOIN sys.schemas pk_schema
                                                        ON pk_table.schema_id = pk_schema.schema_id
                                             INNER JOIN sys.columns pk_column
                                                        ON pk_column.column_id = fkc.referenced_column_id
                                                            AND pk_column.object_id = pk_table.object_id;
                                    

                                    【讨论】:

                                      猜你喜欢
                                      • 2010-11-18
                                      • 2016-03-09
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 2011-03-11
                                      • 2011-06-25
                                      相关资源
                                      最近更新 更多