Come posso scoprire quale vincolo FOREIGN KEY fa riferimento a una tabella in SQL Server?


121

Sto cercando di eliminare una tabella ma ricevo il seguente messaggio:

Msg 3726, livello 16, stato 1, riga 3
Impossibile eliminare l'oggetto "dbo.UserProfile" perché fa riferimento a un vincolo FOREIGN KEY.
Msg 2714, livello 16, stato 6, riga 2
Nel database è già presente un oggetto denominato "UserProfile".

Mi sono guardato intorno con SQL Server Management Studio ma non sono riuscito a trovare il vincolo. Come posso scoprire i vincoli della chiave esterna?


2
Mi piace sp_help 'dbo.TableName' Vedi qui per ulteriori modi: stackoverflow.com/questions/483193/...
Mark Boltuc

2
Worth noticing:La risposta di @LittleSweetSeas restituirà informazioni sulle chiavi esterne PER una data tabella di riferimento , tuttavia i dettagli di risposta di @ Gayathri-Varma per una data tabella padre . Entrambi sono utili in contesti diversi ed entrambi vincono la propria gara :-)
Izhar Aazmi

Risposte:


225

Ecco qui:

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

In questo modo, otterrai la tabella di riferimento e il nome della colonna.

Modificato per utilizzare sys.tables invece di sys.objects generici secondo il suggerimento del commento. Grazie, marc_s


Dovresti usare il più concentrato sys.tablespiuttosto chesys.objects
marc_s

@marc_s: Grazie, ma potresti pubblicare un esempio? AFAIK in sys.tables non ho riferimenti FK
LittleSweetSeas

3
Cosa volevo dire: basta sostituire INNER JOIN sys.objects AS o ON o.OBJECT_ID = fc.referenced_object_idconINNER JOIN sys.tables t ON t.OBJECT_ID = fc.referenced_object_id
marc_s

@LittleSweetSeas avevo eseguito la query di cui sopra ancora non ricevo il nome_oggetto e il nome della colonna per la tabella che aveva un vincolo di chiave esterna
Smart003

Potresti rinforzare la tua selezione con un po 'più di informazioni: SELECT f.name ConstraintName, f.type_desc ConstraintType, OBJECT_NAME (f.parent_object_id) ConstrainedTable, COL_NAME (fc.parent_object_id, fc.parent_column_id) ConstrainedColumn, OBJECT_reference , COL_NAME (fc.referenced_object_id, fc.referenced_column_id) ReferencedColumn
DocOc

74

Un altro modo è controllare i risultati di

sp_help 'TableName'

(o evidenzia semplicemente il TableName citato e premi ALT + F1)

Con il passare del tempo, ho deciso di affinare la mia risposta. Di seguito è riportato uno screenshot dei risultati che sp_helpfornisce. A ho utilizzato il DB AdventureWorksDW2012 per questo esempio. Ci sono molte buone informazioni lì e quello che stiamo cercando è proprio alla fine, evidenziato in verde:

inserisci qui la descrizione dell'immagine


3
+1 Questo fornisce molte informazioni utili e mostra le chiavi esterne nella parte inferiore dell'output
Hux

1
Questo mi dà molte informazioni nel minor numero di righe di codice
Rennish Joseph

Questa è la scorciatoia più bella! Batte completamente Ctl-R per aggiornare lo schema!
Mr. Young,

Aggiorna cache InteliSense locale = Ctrl + Maiusc + R; Ctrl + R = mostra / nascondi riquadro dei risultati (o almeno questi sono i miei valori predefiniti per SSMS2008 e SSMS2014)
Vladislav

44

Prova questo

SELECT
  object_name(parent_object_id) ParentTableName,
  object_name(referenced_object_id) RefTableName,
  name 
FROM sys.foreign_keys
WHERE parent_object_id = object_id('Tablename')

1
Breve ed elegante, in più funziona per me! L'unica cosa è che il namevalore restituito è un nome interno (methinks) e non il nome effettivo della colonna nella tabella padre. Qualche modo per risolvere questo problema?
Hamman Samuel

Quello che vedo qui è che ParentTableNamesarebbe sempre lo stesso del dato Tablename"nella clausola where (se inclusa). Questo può essere intenzionale e sarà più utile se richiesto per più di una tabella.
Izhar Aazmi

28

Ho trovato questa risposta abbastanza semplice e ho fatto il trucco per ciò di cui avevo bisogno: https://stackoverflow.com/a/12956348/652519

Un riepilogo dal collegamento, usa questa query:

EXEC sp_fkeys 'TableName'

Rapido e semplice. Sono stato in grado di individuare abbastanza rapidamente tutte le tabelle delle chiavi esterne, le rispettive colonne ei nomi delle chiavi esterne di 15 tabelle.

Come @mdisibio ha notato di seguito, ecco un collegamento alla documentazione che descrive in dettaglio i diversi parametri che possono essere utilizzati: https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp- fkeys-Transact-SQL


1
Ci sono altri cinque parametri da filtrare, il più utile dei quali sapere è il secondo in cui è possibile specificare uno schema non predefinito, ad esempioEXEC sp_fkeys 'Payroll', 'accounting'
mdisibio

8

Sto usando questo script per trovare tutti i dettagli relativi alla chiave esterna. Sto usando INFORMATION.SCHEMA. Di seguito è riportato uno script SQL:

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

2
Stavo cercando un modo per vedere le colonne che sono chiavi esterne e le tabelle correlate a cui fa riferimento la colonna, e questo lo riassume bene. Grazie!
Nate Kindrew

Mancavano alcune chiavi esterne su alcune delle mie tabelle mentre la risposta di @LittleSweetSeas le ha mostrate
Seafish,

7

se vuoi passare tramite SSMS nella finestra di esplorazione oggetti, fai clic con il pulsante destro del mouse sull'oggetto che desideri rilasciare, visualizza le dipendenze.


7

Ecco il modo migliore per scoprire la relazione di chiave esterna in tutti i database.

exec sp_helpconstraint 'Table Name'

e un altro modo

select * from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME='Table Name'
--and left(CONSTRAINT_NAME,2)='FK'(If you want single key)

Questa soluzione exec sp_helpconstraint 'Table Name'è l'unica che restituisce qualsiasi riga per me. Tuttavia il nome del contraint è incomprensibile. PRIMARY KEY (clustered) PK__org_soft__3213E83FE6B07364
Tor

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

1

- Quanto segue potrebbe darti più di quello che stai cercando:

create Procedure spShowRelationShips 
( 
    @Table varchar(250) = null,
    @RelatedTable varchar(250) = null
)
as
begin
    if @Table is null and @RelatedTable is null
        select  object_name(k.constraint_object_id) ForeginKeyName, 
                object_name(k.Parent_Object_id) TableName, 
                object_name(k.referenced_object_id) RelatedTable, 
                c.Name RelatedColumnName,  
                object_name(rc.object_id) + '.' + rc.name RelatedKeyField
        from sys.foreign_key_columns k
        left join sys.columns c on object_name(c.object_id) = object_name(k.Parent_Object_id) and c.column_id = k.parent_column_id
        left join sys.columns rc on object_name(rc.object_id) = object_name(k.referenced_object_id) and rc.column_id = k.referenced_column_id
        order by 2,3

    if @Table is not null and @RelatedTable is null
        select  object_name(k.constraint_object_id) ForeginKeyName, 
                object_name(k.Parent_Object_id) TableName, 
                object_name(k.referenced_object_id) RelatedTable, 
                c.Name RelatedColumnName,  
                object_name(rc.object_id) + '.' + rc.name RelatedKeyField
        from sys.foreign_key_columns k
        left join sys.columns c on object_name(c.object_id) = object_name(k.Parent_Object_id) and c.column_id = k.parent_column_id
        left join sys.columns rc on object_name(rc.object_id) = object_name(k.referenced_object_id) and rc.column_id = k.referenced_column_id
        where object_name(k.Parent_Object_id) =@Table
        order by 2,3

    if @Table is null and @RelatedTable is not null
        select  object_name(k.constraint_object_id) ForeginKeyName, 
                object_name(k.Parent_Object_id) TableName, 
                object_name(k.referenced_object_id) RelatedTable, 
                c.Name RelatedColumnName,  
                object_name(rc.object_id) + '.' + rc.name RelatedKeyField
        from sys.foreign_key_columns k
        left join sys.columns c on object_name(c.object_id) = object_name(k.Parent_Object_id) and c.column_id = k.parent_column_id
        left join sys.columns rc on object_name(rc.object_id) = object_name(k.referenced_object_id) and rc.column_id = k.referenced_column_id
        where object_name(k.referenced_object_id) =@RelatedTable
        order by 2,3



end

1

Puoi anche restituire tutte le informazioni sulla Foreign Keysrisposta adattando @LittleSweetSeas:

SELECT 
   OBJECT_NAME(f.parent_object_id) ConsTable,
   OBJECT_NAME (f.referenced_object_id) refTable,
   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
order by
ConsTable

1

In SQL Server Management Studio è sufficiente fare clic con il pulsante destro del mouse sulla tabella in Esplora oggetti e selezionare "Visualizza dipendenze". Questo ti darebbe un buon punto di partenza. Mostra tabelle, viste e procedure che fanno riferimento alla tabella.


0

prova la seguente query.

select object_name(sfc.constraint_object_id) AS constraint_name,
       OBJECT_Name(parent_object_id) AS table_name ,
       ac1.name as table_column_name,
       OBJECT_name(referenced_object_id) as reference_table_name,      
       ac2.name as reference_column_name
from  sys.foreign_key_columns sfc
join sys.all_columns ac1 on (ac1.object_id=sfc.parent_object_id and ac1.column_id=sfc.parent_column_id)
join sys.all_columns ac2 on (ac2.object_id=sfc.referenced_object_id and ac2.column_id=sfc.referenced_column_id) 
where sfc.parent_object_id=OBJECT_ID(<main table name>);

questo darà il nome_colonna, nomi_colonna che faranno riferimento e le tabelle che dipenderanno dal vincolo saranno presenti.


0

È possibile utilizzare questa query per visualizzare le Foreign keycostanti:

SELECT
K_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
---- optional:
ORDER BY
1,2,3,4
WHERE PK.TABLE_NAME='YourTable'

Tratto da http://blog.sqlauthority.com/2006/11/01/sql-server-query-to-display-foreign-key-relationships-and-name-of-the-constraint-for-each-table- in-database /


0

Il modo più semplice per ottenere Primary Keye Foreign Keyper un tavolo è:

/*  Get primary key and foreign key for a table */
USE DatabaseName;

SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE CONSTRAINT_NAME LIKE 'PK%' AND
TABLE_NAME = 'TableName'

SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE CONSTRAINT_NAME LIKE 'FK%' AND
TABLE_NAME = 'TableName'

0

In Esplora oggetti, espandere la tabella ed espandere le chiavi:

inserisci qui la descrizione dell'immagine

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.