SQL Server'da belirli bir tabloya başvuran tüm yabancı anahtarları nasıl listeleyebilirim?


736

Bir SQL Server veritabanında çok başvurulan bir tabloyu kaldırmanız gerekiyor. Masayı düşürmek için kaldırmam gereken tüm yabancı anahtar kısıtlamalarının bir listesini nasıl alabilirim?

(SQL yanıtları yönetim stüdyosunun GUI'sine tıklamaktan daha çok tercih edilir.)


Yardım için Tablonun Tüm Yabancı Anahtarlarının Komut Dosyası Nasıl Yazılır? Bölümüne bakın . Güncelleme : Bağlantı artık mevcut değil, ancak ilgili SQL ilgili soruya yanıt olarak kopyalandı . Bağımlılıkları GUI aracılığıyla da görüntüleyebilirsiniz.
08

Yanıtlar:


1126

Neden kimse önerdi emin değilim ama sp_fkeysbelirli bir tablo için yabancı anahtarları sorgulamak için kullanın:

EXEC sp_fkeys 'TableName'

Şemayı da belirtebilirsiniz:

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

Şemayı belirtmeden dokümanlar aşağıdakileri belirtir :

Pktable_owner belirtilmezse, temel DBMS'nin varsayılan tablo görünürlük kuralları uygulanır.

SQL Server'da, geçerli kullanıcının belirtilen ada sahip bir tablosu varsa, o tablonun sütunları döndürülür. Pktable_owner belirtilmezse ve geçerli kullanıcının belirtilen pktable_name değerine sahip bir tablosu yoksa, yordam, veritabanı sahibinin sahip olduğu belirtilen pktable_name değerine sahip bir tablo arar. Varsa, tablonun sütunları döndürülür.


41
Bu benim için bir neden 2008 sql veritabanında çalışmıyor. sp_help ilişkileri gösterir, ancak bu komut gösterilmez.
tbone

21
@tbone: Parametreleri tam olarak belirtmemekle ilgili aynı sorunu yaşadım. O'nun sahip olduğu tablo T'de, D veritabanında EXEC sp_fkeys \ @ pktable_name = 'T', \ @ pktable_owner = 'O', \ @ pktable_qualifier = 'D' EXEC sp_tables \ 'ın çıktısına bakmayı deneyin \ @ Parametre değerlerinin ne olması gerektiğini anlamak için table_name = 'T'.
Mads Ravn

3
@JustinRusso Bir tablo oluşturarak bunun üstesinden gelebilir, sonucu tabloya kaydedebilir ve ardından belirli sütunları seçebilirsiniz. Bir örnek için bu bağlantıya göz atın :).
John Odom

3
SSMS 2014'te iyi çalışıyor. Teşekkürler.
AH.

7
Yukarıdaki yorumlarda zaten yanıtlanmıştır: ancak sadece netlik için - EXEC sp_fkeys @pktable_name = N'Department ', @ pktable_owner = N'dbo'; msdn.microsoft.com/tr-NZ/library/ms175090.aspx
Tejas Patel

233

SQL Server Management Studio'da Veritabanı Diyagramı özelliğini kullanardım, ancak bunu dışladığınızdan beri - bu benim için SQL Server 2008'de çalıştı (2005'e sahip değil).

Yönlendiren tablo ve sütun adlarının listesini almak için ...

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

Yabancı anahtar kısıtlamalarının isimlerini almak

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

4
great, üst öğe yerine başvurulan_object_id kullanılır. object_id sys.objects farklı adı seçin (burada fk.referenced_object_id = (sys.tables gelen object_id seçmek fk olarak sys.foreign_key_columns gelen fk.constraint_object_id seçmek burada adı = 'tabloismi'))
chillitom

4
İlk sorgu seçimine "object_name (constraint_object_id)" ekleyerek FK adını alabilirsiniz.
sam yi

3
Object_id ('TableOthersForeignKeyInto') kimliğini alabilirsiniz
IvanH

189

Bu size şunları sağlar:

  • FK'nin kendisi
  • FK'nin ait olduğu şema
  • " Referans tablosu " veya FK içeren tablo
  • " Referans sütun " veya referans tablosunun içinde FK işaret eden sütun
  • " Referans verilen tablo " veya FK'nizin işaret ettiği anahtar sütunu içeren tablo
  • " Referans verilen sütun " veya FK'nizin işaret ettiği anahtar olan sütun

Aşağıdaki kod:

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

13
Sonuçları daha sonra filtrelemek istiyorsanız, bu benim fikrimdeki en iyi cevap.
Faliorn

Harika çalışıyor! Aşağıdakileri yapsanız daha da iyi olur: a) tüm Sütun Adlarını "Fk" / "Anahtar" ile önekleyin, b) tüm Sütun Adlarını "Ad" ile sonekleyin, c) alt çizgileri kaldırın, d) KeyTableSchemaName ekleyin, e) varsayılan ekle order by: KeyTableSchemaName, KeyTableName, KeyColumnName, FkTableSchemaName, FkTableName, FkName ve f) Sütun sırasını şu şekilde değiştirin: KeyTableSchemaName, KeyTableName, KeyColumnName, FkTableSchemaName, FkTableName, FkTableName, FkTableName, Fkency / Name, FkTableName, Fkency / name, Fkency / name, FkTableName, Fkency / name, Fkency kurallar ve en olası kullanım için d / e (a'nın FK bağımlılarını listeler Table).
Tom

Böyle harika bir cevap ve kullanışlı bir sorgu. Teşekkür ederim
Rich Dominelli

153

Bunu dene :

sp_help 'TableName'

2
Elle db keşfetmek olup olmadığını bilmek güzel bir yardımcı yöntem. Ayrıca, Azure SQL Server üzerinde çalışır.
Pac0

48

Diğer nesnelere yapılan göndermelere de dikkat etmelisiniz.

Tabloya diğer tablolar tarafından büyük ölçüde başvuru yapıldıysa, muhtemelen görünümler, saklı yordamlar, işlevler ve daha fazlası gibi diğer nesneler tarafından da büyük ölçüde başvuruda bulunulur.

Gerçekten SSMS 'görünüm bağımlılıkları' iletişim kutusu gibi GUI aracı veya ApexSQL gibi ücretsiz bir araç tavsiye ederim çünkü diğer nesnelerde bağımlılıkları aramak sadece SQL ile yapmak istiyorsanız hata eğilimli olabilir.

SQL tek seçenekse, bunu böyle deneyebilirsiniz.

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%'

21

Orijinal soru, tablonun kaldırılabilmesi için tüm yabancı anahtarların bir listesini yüksek referanslı bir tabloya almasını istedi.

Bu küçük sorgu, tüm yabancı anahtarları belirli bir tabloya bırakmak için gereken tüm 'yabancı anahtar bırak' komutlarını döndürür:

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'

Örnek çıktı:

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

Geçerli veritabanındaki tüm yabancı anahtarlar için bırakma komutlarını almak için WHERE yan tümcesini atlayın.


17

İşte kullanacağım SQL kodu.

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

Özellikle açık SQL değil, bu yüzden bir örneğe bakalım.

Diyelim ki EmployeesMicrosoft'un sevilen Northwindveritabanındaki tabloyu bırakmak istedim , ancak SQL Server bana bir veya daha fazla Yabancı Anahtarın bunu yapmamı engellediğini söyledi.

Yukarıdaki SQL komutu bu sonuçları döndürür ...

Yabancı Anahtarlar

Tabloya referans veren 3 Yabancı Anahtar olduğunu gösteriyor Employees. Başka bir deyişle, bu üç Yabancı Anahtar ilk önce silinene kadar bu tabloyu silmeme (bırakma) izin verilmez.

Sonuçlarda, ilk satır aşağıdaki Yabancı Anahtar kısıtlamasının sonuçlarda nasıl gösterileceğidir.

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

Sondan ikinci sütuna, bu Yabancı Anahtarlardan birini silmek için kullanmanız gereken SQL komutunu gösterir;

ALTER TABLE [Employees] DROP CONSTRAINT [FK_Employees_Employees]

... ve sağdaki sütun onu oluşturmak için SQL'i gösterir ...

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

Tüm bu komutlarla, bir tabloyu silebilmeniz ve daha sonra yeniden oluşturabilmeniz için ilgili Yabancı Anahtarları silmek için ihtiyacınız olan her şeye sahipsiniz.

Uf. Bu yardımcı olur umarım.


İç birleşim ve çapraz birleşimler yerine yan tümceler kullanırsanız daha açık olurdu. Ama bu yardımcı olmayan az oldu!
TamusJRoyce

16
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

15

En basit olanı SQL'de sys.foreign_keys_columns kullanmaktır. Burada tablo, atıfta bulunulan sütun kimliğine göre tüm yabancı anahtarların Nesne kimliklerini ve Başvuru Sütunları ve Tablolarını içerir. Kimlikler sabit kaldıkça sonuç, Şema ve tablolardaki diğer değişiklikler için güvenilir olacaktır.

Sorgu:

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' kullanarak da filtre ekleyebiliriz

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

Bu, başvurulan tabloların tüm DB yapılarını / kümelerini kaldırmanız gerektiğinde mükemmeldir.
Morvael

12
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

Yabancı anahtarla ilgili tüm ayrıntıları bulmak için bu komut dosyasını kullanıyorum. BİLGİ.SCHEMA kullanıyorum. Aşağıda bir SQL Script bulunmaktadır:

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


5

Yukarıda bazı iyi cevaplar. Ama tek bir sorgu ile cevap almayı tercih ederim . Bu kod parçası sys.sp_helpconstraint (sys proc) adresinden alınmıştır.

Tbl ile ilişkili yabancı anahtarlar varsa Microsoft bu şekilde bakar.

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

Cevap şu şekilde görünecektir: test_db_name.dbo.Hesap: FK_Account_Customer


3
Bu aslında 4 ayrı sorgu deyimi gibidir ... bu etkili bir şekilde aynı ifadeyi yapar: 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')
hajikelist

5
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'

Tüm tabloların yabancı anahtar ilişkisini almak istiyorsanız, whereyan tümceyi hariç tutun.tablename


4
 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')

Bu, yalnızca yabancı anahtar kısıtlamaları olduğunda ilişkiyi gösterir. Veritabanım görünüşe göre FK kısıtlamasından önce geliyor.Bazı tablo, referans bütünlüğünü zorunlu kılmak için tetikleyicileri kullanıyor ve bazen ilişkiyi belirtmek için benzer şekilde adlandırılmış bir sütundan başka bir şey yok (ve hiç referans bütünlüğü yok).

Neyse ki, tutarlı bir adlandırma sahnesine sahibiz, bu yüzden referans tabloları ve görünümleri bulabiliriz:

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

Ben bir komut dosyası oluşturmak için temel olarak bu seçimi kullanılan ilgili tablolarda ne yapmak gerekir.


3

@Gishu'nun ne yaptığını çalışarak SQL Server 2005'te aşağıdaki SQL'i üretip kullanabildim

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;

Hangi Tablolar, sütunlar ve Yabancı Anahtar adları 1 sorguda görüntüler.


3

Veritabanındaki tüm tablolar için birincil anahtarları ve benzersiz anahtarları belirleme ...

Bu, tüm kısıtlamaları listelemeli ve sonunda filtrelerinizi koyabilirsiniz

/* 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;

Referans için lütfen şu adresi okuyun - http://blogs.msdn.com/b/sqltips/archive/2005/09/16/469136.aspx


2
Bu, sorulan soru için çok fazla bilgi içeriyor. Sadece soruyu cevaplamak için bir açıklama ekleyebilir misiniz (ve ekstra kodu kaldırabilir misiniz)? Bu cevabı iki farklı soruya gönderdiniz ve her birinin bu cevabın sadece bir kısmına ihtiyacı var .
Andrew Barber

2
Cevabı düzenledim - Bir veritabanındaki tüm tablolar için birincil anahtarları ve benzersiz anahtarları belirleyin ... Burada yanıtın uygun olduğunu düşünüyorum, çünkü soru tüm referanslar için.
dekdev

3

Bunu 2008 ve sonrasında kullanıyorum. Listelenen bazı diğer çözümlere benzer, ancak alan adları duruma özel (LatBin) harmanlamaları işlemek için uygun kasalıdır. Ayrıca, tek bir tablo adı besleyebilir ve yalnızca o tablo için bilgi alabilirsiniz.

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

2

Seçilen kimlik için tüm sorumlulukların nasıl hesaplanacağı vardır. Sadece @dbTableName değerini, @dbRowId değerini ve türünü değiştirin (eğer 82 numaralı satırdaki '' öğesini kaldırmanız gerekiyorsa (..SET @SQL = ..)). Zevk almak.

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

2

Mysql sunucusu information_schema.REFERENTIAL_CONSTRAINTSFYI tablosuna sahiptir , tablo adına veya başvurulan tablo adına göre filtreleyebilirsiniz.


2

SQL Server'da belirli bir tabloya başvuran tüm yabancı anahtarların listesi:

Aşağıdaki tabloyu kullanarak başvuru tablosu adını ve sütun adını alabilirsiniz ...

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'

Ve anlayışınız için aşağıdaki ekran görüntüsü ...

resim açıklamasını buraya girin


1

Bu, seçilen tabloyu içeren herhangi bir yabancı anahtarı alır. * _FIRSTABLENAME_SECONDTABLENAME biçimini varsayar.

 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 )

Bu daha genel bir form:

 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]' 

1

Aşağıdaki çözüm benim için çalışıyor:

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

0

Aşağıdaki sorgu ile bulabilirsiniz:

 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)

0

Ayrıca denemek.

EXEC sp_fkeys 'tableName', 'schemaName'

ile sp_fkeyssize pk tablo adı ve şema değil, aynı zamanda fk tablo adı ve şema ile sadece tarafından sonucunu filtre edebilir. bağlantı


0

@BankZ tarafından en çok tercih edilen cevap

sp_help 'TableName'   

ek olarak farklı şema için

sp_help 'schemaName.TableName'   
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.