외래 키를 참조 테이블 / 열에 일치시키는 간단한 쿼리는 다음과 같습니다.
SELECT
o1.name AS FK_table,
c1.name AS FK_column,
fk.name AS FK_name,
o2.name AS PK_table,
c2.name AS PK_column,
pk.name AS PK_name,
fk.delete_referential_action_desc AS Delete_Action,
fk.update_referential_action_desc AS Update_Action
FROM sys.objects o1
INNER JOIN sys.foreign_keys fk
ON o1.object_id = fk.parent_object_id
INNER JOIN sys.foreign_key_columns fkc
ON fk.object_id = fkc.constraint_object_id
INNER JOIN sys.columns c1
ON fkc.parent_object_id = c1.object_id
AND fkc.parent_column_id = c1.column_id
INNER JOIN sys.columns c2
ON fkc.referenced_object_id = c2.object_id
AND fkc.referenced_column_id = c2.column_id
INNER JOIN sys.objects o2
ON fk.referenced_object_id = o2.object_id
INNER JOIN sys.key_constraints pk
ON fk.referenced_object_id = pk.parent_object_id
AND fk.key_index_id = pk.unique_index_id
ORDER BY o1.name, o2.name, fkc.constraint_column_id
출력에는 외래 키의 테이블 및 열 이름 (FK_table, FK_column), 외래 키 제약 조건의 이름 (FK_name), 참조 된 PK 또는 고유 인덱스 테이블 및 열 이름 (PK_table, PK_column), 참조 된 PK 또는 고유 색인의 이름 (PK_name) 및 갱신 / 삭제 계단식 조치 (Delete_Action, Update_Action).
(출력 열을 더 추가하도록 편집되었습니다.)
편집 : 6 년 후에 개선 된 버전으로 돌아 왔습니다. 원래 쿼리가 실제로 다중 열 외래 키를 제대로 처리하지 못한다는 것을 깨달았으며 비활성화되거나 신뢰할 수 없거나 색인이 생성되지 않은 외래 키를 신속하게 식별하고 싶었습니다. 이 모든 것을 수정하는 새로운 버전이 있습니다.
여러 열 키는 전통적인 / 남용을 사용하여 FK_columns
및 로 쉼표로 구분 된 목록으로 표시됩니다 . 이 열에는 외래 키 열 (주로 기본 키 테이블에 대한 삭제 또는 업데이트를 최적화하는 데 사용)을 사용하여 검색을 만족시키는 데 사용될 수있는 외래 키 테이블의 인덱스 이름이 표시됩니다. 이 경우 인덱싱되지 않은 외래 키가 있습니다. PK 테이블 이름을 기준으로 정렬하거나 특정 PK / FK 테이블을 필터링하는 등의 방법 으로을 조정 하거나 절 (아래 주석)을 추가 할 수 있습니다 .PK_columns
FOR XML
STUFF
FK_indexes
NULL
ORDER BY
WHERE
SELECT
fk.is_disabled,
fk.is_not_trusted,
OBJECT_SCHEMA_NAME(o1.object_id) AS FK_schema,
o1.name AS FK_table,
--Generate list of columns in referring side of foreign key
STUFF(
(
SELECT ', ' + c1.name AS [text()]
FROM sys.columns c1 INNER
JOIN sys.foreign_key_columns fkc
ON c1.object_id = fkc.parent_object_id
AND c1.column_id = fkc.parent_column_id
WHERE fkc.constraint_object_id = fk.object_id
FOR XML PATH('')
), 1, 2, '') AS FK_columns,
--Look for any indexes that will fully satisfy the foreign key columns
STUFF(
(
SELECT ', ' + i.name AS [text()]
FROM sys.indexes i
WHERE i.object_id = o1.object_id
AND NOT EXISTS ( --Find foreign key columns that don't match the index key columns
SELECT fkc.constraint_column_id, fkc.parent_column_id
FROM sys.foreign_key_columns fkc
WHERE fkc.constraint_object_id = fk.object_id
EXCEPT
SELECT ic.key_ordinal, ic.column_id
FROM sys.index_columns ic
WHERE ic.object_id = i.object_id AND ic.index_id = i.index_id
)
FOR XML PATH('')
), 1, 2, '') AS FK_indexes,
fk.name AS FK_name,
OBJECT_SCHEMA_NAME(o2.object_id) AS PK_schema,
o2.name AS PK_table,
--Generate list of columns in referenced (i.e. PK) side of foreign key
STUFF(
(
SELECT ', ' + c2.name AS [text()]
FROM sys.columns c2
INNER JOIN sys.foreign_key_columns fkc
ON c2.object_id = fkc.referenced_object_id
AND c2.column_id = fkc.referenced_column_id
WHERE fkc.constraint_object_id = fk.object_id
FOR XML PATH('')
), 1, 2, '') AS PK_columns,
pk.name AS PK_name,
fk.delete_referential_action_desc AS Delete_Action,
fk.update_referential_action_desc AS Update_Action
FROM sys.objects o1
INNER JOIN sys.foreign_keys fk
ON o1.object_id = fk.parent_object_id
INNER JOIN sys.objects o2
ON fk.referenced_object_id = o2.object_id
INNER JOIN sys.key_constraints pk
ON fk.referenced_object_id = pk.parent_object_id
AND fk.key_index_id = pk.unique_index_id
--WHERE o2.name = 'Company_Address'
ORDER BY o1.name, o2.name