Yabancı anahtarları başvurulan tablolarla / sütunlarla eşleştirmek için basit bir sorgu:
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
Çıktıda sekiz sütun vardır: yabancı anahtarlar için tablo ve sütun adları (FK_table, FK_column), yabancı anahtar kısıtlamalarının adları (FK_name), başvurulan PK veya benzersiz dizin tablosu ve sütun adları (PK_table, PK_column), atıfta bulunulan PK veya benzersiz dizinin adı (PK_name) ve basamaklı eylemleri güncelle / sil (Delete_Action, Update_Action).
(Daha fazla çıktı sütunu eklemek için düzenlendi.)
EDIT: 6 yıl sonra bunun geliştirilmiş bir sürümü ile geri döndüm. Orijinal sorgunun gerçekten çok sütunlu yabancı anahtarları iyi işlemediğini fark ettim ve ayrıca devre dışı, güvenilmeyen veya dizine eklenmemiş yabancı anahtarları hızlı bir şekilde tanımlamak istedim. İşte tüm bunları düzelten yeni sürüm.
Çok kolon anahtarlar virgülle ayrılmış listeler halinde gösterilmiştir FK_columns
ve PK_columns
geleneksel kullanılarak, FOR XML
/ STUFF
kötüye. FK_indexes
Sütun Şekil potansiyel olarak karşılamak için kullanılabilir yabancı anahtar tablo herhangi bir dizin isimleri (özellikle birincil anahtar tablosuna siler veya güncelleştirme optimize etmek için) yabancı anahtar sütunları kullanılarak olarak istediği. Eğer öyleyse NULL
, endekssiz bir yabancı anahtarınız var. PK tablo adına göre sıralamak, belirli PK / FK tabloları için filtre yapmak, vb. Yapmak isterseniz ORDER BY
, ayarını yapabilir veya bir WHERE
cümle ekleyebilirsiniz (aşağıda yorumlanmıştır).
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