Belirli bir sütundaki tüm yabancı anahtar bağımlılıklarını nasıl bulabilirim?
Farklı alternatifler nelerdir (SSMS'de grafik olarak, SQL Server'da sorgular / görünümler, 3. taraf veritabanı araçları, .NET'te kod)?
Belirli bir sütundaki tüm yabancı anahtar bağımlılıklarını nasıl bulabilirim?
Farklı alternatifler nelerdir (SSMS'de grafik olarak, SQL Server'da sorgular / görünümler, 3. taraf veritabanı araçları, .NET'te kod)?
Yanıtlar:
Aşağıdaki sorgu başlamanıza yardımcı olacaktır. Geçerli veritabanındaki tüm Yabancı Anahtar İlişkilerini listeler.
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
İlişkileri, Grafik Diyagramları içindeki SQL Server Management stüdyosunda grafiksel olarak da görüntüleyebilirsiniz.
Deneyin: sp_help [table_name]
tüm yabancı anahtarlar da dahil olmak üzere tablo hakkında tüm bilgileri alacaksınız
sp_fkeys [table]
sp_fkeys @fktable_name='TableName'
Bir tabloyu veya sütunu silmeyi veya yeniden adlandırmayı planlıyorsanız, yalnızca yabancı anahtar bağımlılıkları bulmak yeterli olmayabilir.
Yabancı anahtarla bağlı olmayan referans tabloları - Ayrıca , yabancı anahtarla bağlanamayan referans tablolarını da aramanız gerekir (Yabancı anahtarlar tanımlanmamış, ancak ilgili veriler içeren kötü tasarımlı birçok veritabanı gördüm. ). Çözüm, tüm tablolarda sütun adı aramak ve benzer sütunları aramak olabilir.
Diğer veritabanı nesneleri - bu muhtemelen biraz konu dışıdır, ancak tüm referansları arıyorsanız, bağımlı nesneleri kontrol etmek de önemlidir.
GUI Araçları - Yabancı anahtarla bağlı tablolar da dahil olmak üzere tüm bağımlı nesneleri tanımlamak için SSMS “İlgili nesneleri bul” seçeneğini veya ApexSQL Arama (ücretsiz araç, SSMS'ye entegre) gibi araçları deneyin .
Sorunuz tek bir tabloya yönelik olduğundan, bunu kullanabilirsiniz:
EXEC sp_fkeys 'TableName'
Ben burada SO buldum:
https://stackoverflow.com/a/12956348/652519
İhtiyacım olan bilgiyi çok çabuk buldum. Yabancı anahtarın tablosunu, sütununu ve adını listeler.
DÜZENLE
Kullanılabilecek farklı parametreleri ayrıntılarıyla gösteren belgelere bir bağlantı: 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
Gerçekten kullanmak istediğim bir tanesi Red Gate Software tarafından SQL Bağımlılık İzleyicisi . Tablolar, saklı yordamlar vb. Gibi herhangi bir veritabanı nesnesini / nesnelerini koyabilirsiniz ve daha sonra otomatik olarak seçtiğiniz öğelere dayanan diğer tüm nesneler arasındaki ilişki çizgilerini çizecektir.
Şemanızdaki bağımlılıkların çok iyi bir grafik temsilini verir.
John Sansom'a çok teşekkürler, sorgusu müthiş!
Ayrıca: sorgunuzun sonuna "AND PT.ORDINAL_POSITION = CU.ORDINAL_POSITION" eklemeniz gerekir.
Birincil anahtarda birden fazla alanınız varsa, bu ifade karşılık gelen alanları birbiriyle eşleştirecektir (durumum vardı, sorgunuz tüm kombinasyonları oluşturdu, bu nedenle birincil anahtardaki 2 alan için karşılık gelen yabancı anahtar için 4 sonuç aldım) .
(Üzgünüm John'un cevabını yorumlayamam çünkü yeterince itibar puanım yok).
Bu sorgu bir tablodaki yabancı anahtarlarla ilgili ayrıntıları döndürür, birden çok sütun anahtarını destekler.
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'
Uzun aramalardan sonra çalışan bir çözüm buldum. Veritabanım sys.foreign_key_columns kullanmıyor ve information_schema.key_column_usage yalnızca birincil anahtarlar içeriyor.
SQL Server 2015 kullanıyorum
ÇÖZÜM 1 (nadiren kullanılır)
Diğer çözümler işe yaramazsa, bu iyi çalışır:
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
ÇÖZÜM 2 (yaygın olarak kullanılır)
Çoğu durumda bu işe yarayacaktır:
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
Bir tablonun yabancı anahtar meta verisini almak için BİLGİ_SCHEMA.KEY_COLUMN_USAGE ve sys.foreign_key_columns komutlarını kullanabilirsiniz, yani Kısıtlama adı, Referans tablosu ve Referans sütunu vb.
Sorgu aşağıdadır:
SELECT CONSTRAINT_NAME, COLUMN_NAME, ParentTableName, RefTableName,RefColName FROM
(SELECT CONSTRAINT_NAME,COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME = '<tableName>') constraint_details
INNER JOIN
(SELECT ParentTableName, RefTableName,name ,COL_NAME(fc.referenced_object_id,fc.referenced_column_id) RefColName FROM (SELECT object_name(parent_object_id) ParentTableName,object_name(referenced_object_id) RefTableName,name,OBJECT_ID FROM sys.foreign_keys WHERE parent_object_id = object_id('<tableName>') ) f
INNER JOIN
sys.foreign_key_columns AS fc ON f.OBJECT_ID = fc.constraint_object_id ) foreign_key_detail
on foreign_key_detail.name = constraint_details.CONSTRAINT_NAME
@ "John Sansom" cevabı için bir not,
Eğer yabancı anahtar bağımlılıkları aranır, ben PT fıkra Nerede olması gerektiğini düşünüyorum:
i1.CONSTRAINT_TYPE = 'FOREIGN KEY' -- instead of 'PRIMARY KEY'
ve AÇIK durumu:
ON PT.TABLE_NAME = FK.TABLE_NAME – instead of PK.TABLE_NAME
Yabancı tablonun birincil anahtarı yaygın olarak kullanıldığından, bu konunun daha önce fark edilmediğini düşünüyorum.
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
Size verecek:
FK'nin kendisi FK'nin ait olduğu şema