如何在SQL Server中查找外键依赖关系?

如何find特定列上的所有外键依赖关系?

有什么不同的select(SSMS中的graphics,SQL Server中的查询/视图,第三方数据库工具,.NET代码)?

以下查询将帮助您开始。 它列出了当前数据库中的所有外键关系。

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

您还可以在数据库图表内的SQL Server Management Studio中以graphics方式查看关系。

请尝试: sp_help [table_name]

您将获得有关表格的所有信息,包括所有外键

如果您打算删除或重命名表或列,只find外键依赖性可能不够。

引用不与外键连接的表 – 你还需要search引用的表可能不与外键连接(我看到许多数据库devise不好,没有定义外键,但有相关数据)。 解决scheme可能是search所有表中的列名称并查找相似的列。

其他数据库对象 – 这可能是有点偏离主题,但如果您正在寻找所有引用,而检查依赖对象也很重要。

graphics用户界面工具 – 尝试SSMS“查找相关对象”选项或工具,如ApexSQLsearch (免费工具,集成到SSMS),以确定所有依赖对象,包括与外键连接的表。

因为你的问题是针对一个表,你可以使用这个:

 EXEC sp_fkeys 'TableName' 

我在这里发现它:

https://stackoverflow.com/a/12956348/652519

我很快find了我需要的信息。 它列出了外键的表,列和名称。

编辑

以下是指向可以使用的不同参数的文档的链接: https : //docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-fkeys-transact-sql

我觉得这个脚本比较便宜:

 SELECT f.name AS ForeignKey, OBJECT_NAME(f.parent_object_id) AS TableName, COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ColumnName, OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName, COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS ReferenceColumnName FROM sys.foreign_keys AS f INNER JOIN sys.foreign_key_columns AS fc ON f.OBJECT_ID = fc.constraint_object_id 

我真正喜欢使用的是Red Gate Software的 SQL Dependency Tracker。 您可以放入任何数据库对象,如表,存储过程等,然后它将自动绘制所有依赖于您select的项目的其他对象之间的关系线。

在您的模式中给出一个很好的graphics表示。

非常感谢John Sansom,他的提问太棒了!

另外:你应该在查询结尾添加“AND PT.ORDINAL_POSITION = CU.ORDINAL_POSITION”。

如果你在主键中有多个字段,这个语句将匹配对应的字段(我有这种情况,你的查询确实创build了所有组合,所以对于主键中的2个字段,我有4个结果用于对应的外键) 。

(对不起,我不能评论约翰的答案,因为我没有足够的声望点)。

此查询将返回有关表中外键的详细信息,它支持多个列键。

  SELECT * FROM ( SELECT T1.constraint_name ConstraintName, T2.COLUMN_NAME ColumnName, T3.TABLE_NAME RefTableName, T3.COLUMN_NAME RefColumnName, T1.MATCH_OPTION MatchOption, T1.UPDATE_RULE UpdateRule, T1.DELETE_RULE DeleteRule FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS T1 INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE T2 ON T1.CONSTRAINT_NAME = T2.CONSTRAINT_NAME INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE T3 ON T1.UNIQUE_CONSTRAINT_NAME = T3.CONSTRAINT_NAME AND T2.ORDINAL_POSITION = T3.ORDINAL_POSITION) A WHERE A.ConstraintName = 'table_name' 

经过漫长的search,我find了一个工作解 我的数据库不使用sys.foreign_key_columns,而information_schema.key_column_usage只包含主键。

我使用SQL Server 2015

解决scheme1(很less使用)

如果其他解决scheme不起作用,这将工作正常:

  WITH CTE AS ( SELECT TAB.schema_id, TAB.name, COL.name AS COLNAME, COl.is_identity FROM sys.tables TAB INNER JOIN sys.columns COL ON TAB.object_id = COL.object_id ) SELECT DB_NAME() AS [Database], SCHEMA_NAME(Child.schema_id) AS 'Schema', Child.name AS 'ChildTable', Child.COLNAME AS 'ChildColumn', Parent.name AS 'ParentTable', Parent.COLNAME AS 'ParentColumn' FROM cte Child INNER JOIN CTE Parent ON Child.COLNAME=Parent.COLNAME AND Child.name<>Parent.name AND Child.is_identity+1=Parent.is_identity 

解决scheme2(常用)

在大多数情况下,这将工作得很好:

  SELECT DB_NAME() AS [Database], SCHEMA_NAME(fk.schema_id) AS 'Schema', fk.name 'Name', tp.name 'ParentTable', cp.name 'ParentColumn', cp.column_id, tr.name 'ChildTable', cr.name 'ChildColumn', cr.column_id FROM sys.foreign_keys fk INNER JOIN sys.tables tp ON fk.parent_object_id = tp.object_id INNER JOIN sys.tables tr ON fk.referenced_object_id = tr.object_id INNER JOIN sys.foreign_key_columns fkc ON fkc.constraint_object_id = fk.object_id INNER JOIN sys.columns cp ON fkc.parent_column_id = cp.column_id AND fkc.parent_object_id = cp.object_id INNER JOIN sys.columns cr ON fkc.referenced_column_id = cr.column_id AND fkc.referenced_object_id = cr.object_id WHERE -- CONCAT(SCHEMA_NAME(fk.schema_id), '.', tp.name, '.', cp.name) LIKE '%my_table_name%' OR -- CONCAT(SCHEMA_NAME(fk.schema_id), '.', tr.name, '.', cr.name) LIKE '%my_table_name%' ORDER BY tp.name, cp.column_id 

只是@“John Sansom”的回答,

如果寻求外键依赖关系,我认为PT Where子句应该是:

 i1.CONSTRAINT_TYPE = 'FOREIGN KEY' -- instead of 'PRIMARY KEY' 

和它的ON条件:

 ON PT.TABLE_NAME = FK.TABLE_NAME – instead of PK.TABLE_NAME 

由于通常使用的是外键的主键,我觉得这个问题以前没有注意到。

使用information_schema;

 SELECT COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME FROM KEY_COLUMN_USAGE WHERE (table_name = *tablename*) AND NOT (REFERENCED_TABLE_NAME IS NULL)