Wie kann ich herausfinden, welche FOREIGN KEY-Einschränkung auf eine Tabelle in SQL Server verweist?

119

Ich versuche, eine Tabelle zu löschen, erhalte jedoch die folgende Meldung:

Meldung 3726, Ebene 16,
Status 1, Zeile 3 Das Objekt 'dbo.UserProfile' konnte nicht gelöscht werden, da es durch eine FOREIGN KEY-Einschränkung referenziert wird.
Meldung 2714, Ebene 16,
Status 6, Zeile 2 In der Datenbank befindet sich bereits ein Objekt mit dem Namen 'UserProfile'.

Ich habe mich mit SQL Server Management Studio umgesehen, kann die Einschränkung jedoch nicht finden. Wie kann ich die Fremdschlüsseleinschränkungen herausfinden?

marc_s
quelle
2
Ich mag sp_help 'dbo.TableName' Weitere Möglichkeiten finden Sie hier: stackoverflow.com/questions/483193/…
Mark Boltuc
2
Worth noticing:Die Antwort von @LittleSweetSeas gibt Informationen zu den Fremdschlüsseln für eine bestimmte referenzierte Tabelle zurück , jedoch die Antwortdetails von @ Gayathri-Varma für eine bestimmte übergeordnete Tabelle . Beide sind in unterschiedlichen Zusammenhängen nützlich und beide gewinnen ihr eigenes Rennen :-)
Izhar Aazmi

Antworten:

223

Hier ist es:

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'

Auf diese Weise erhalten Sie den Namen der referenzierenden Tabelle und der Spalte.

Bearbeitet, um sys.tables anstelle von generischen sys.objects gemäß Kommentarvorschlag zu verwenden. Danke, marc_s

LittleSweetSeas
quelle
Sie sollten die fokussiertere verwenden sys.tablesalssys.objects
marc_s
@marc_s: Danke, aber könntest du ein Beispiel posten? AFAIK in sys.tables Ich habe keine FK Referenzen
LittleSweetSeas
3
Was ich gemeint: ersetzen Sie einfach INNER JOIN sys.objects AS o ON o.OBJECT_ID = fc.referenced_object_idmitINNER JOIN sys.tables t ON t.OBJECT_ID = fc.referenced_object_id
marc_s
@LittleSweetSeas Ich hatte die obige Abfrage ausgeführt, aber ich erhalte nicht den Objektnamen und den Spaltennamen für die Tabelle, die eine Fremdschlüsseleinschränkung hatte
Smart003
Sie können Ihre Auswahl mit ein wenig mehr Informationen erweitern: 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_NA , COL_NAME (fc.referenced_object_id, fc.referenced_column_id) ReferencedColumn
DocOc
73

Eine andere Möglichkeit besteht darin, die Ergebnisse von zu überprüfen

sp_help 'TableName'

(oder markieren Sie einfach den angegebenen Tabellennamen und drücken Sie ALT + F1)

Mit der Zeit habe ich mich entschlossen, meine Antwort zu verfeinern. Unten sehen Sie einen Screenshot der Ergebnisse sp_help. A hat für dieses Beispiel die AdventureWorksDW2012-Datenbank verwendet. Dort gibt es zahlreiche gute Informationen, und was wir suchen, ist ganz am Ende - grün hervorgehoben:

Geben Sie hier die Bildbeschreibung ein

Vladislav
quelle
3
+1 Dies gibt viele hilfreiche Informationen und zeigt Fremdschlüssel am unteren Rand der Ausgabe
Hux
1
Dies gibt mir viele Informationen in der kleinsten Anzahl von Codezeilen
Rennish Joseph
Dies ist die coolste Abkürzung! Schlägt Ctl-R vollständig, um das Schema zu aktualisieren!
Mr. Young
Lokalen InteliSense-Cache aktualisieren = Strg + Umschalt + R; Strg + R = Ergebnisbereich ein- / ausblenden (oder zumindest sind dies meine Standardeinstellungen für SSMS2008 und SSMS2014)
Vladislav
44

Versuche dies

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')
Gayathri L.
quelle
1
Kurz und elegant, plus funktioniert für mich! Der einzige zurückgegebene nameWert ist ein interner Name (Methinks) und nicht der tatsächliche Spaltenname in der übergeordneten Tabelle. Wie kann man das beheben?
Hamman Samuel
Was ich hier sehe, ist, dass das ParentTableNameimmer das gleiche ist wie das Tablenamein der where-Klausel angegebene ' ' (falls enthalten). Dies kann beabsichtigt sein und ist nützlicher, wenn mehr als eine Tabelle abgefragt wird .
Izhar Aazmi
28

Ich fand diese Antwort ziemlich einfach und tat den Trick für das, was ich brauchte: https://stackoverflow.com/a/12956348/652519

Verwenden Sie diese Zusammenfassung, um eine Zusammenfassung des Links zu erhalten:

EXEC sp_fkeys 'TableName'

Schnell und einfach. Ich konnte ziemlich schnell alle Fremdschlüsseltabellen, entsprechenden Spalten und Fremdschlüsselnamen von 15 Tabellen finden.

Wie unten in @mdisibio angegeben, finden Sie hier einen Link zur Dokumentation, in der die verschiedenen Parameter aufgeführt sind, die verwendet werden können: https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp- fkeys-transact-sql

Michael
quelle
1
Es gibt fünf weitere Parameter, nach denen gefiltert werden kann. Der nützlichste ist der zweite, bei dem Sie ein nicht standardmäßiges Schema angeben können, z. B.EXEC sp_fkeys 'Payroll', 'accounting'
mdisibio
8

Ich verwende dieses Skript, um alle Details zum Fremdschlüssel zu finden. Ich benutze INFORMATION.SCHEMA. Unten ist ein SQL-Skript:

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
Anvesh
quelle
2
Ich habe nach einer Möglichkeit gesucht, die Spalten zu sehen, die Fremdschlüssel sind, und die zugehörigen Tabellen, auf die die Spalte verweist, und dies fasst es gut zusammen. Vielen Dank!
Nate Kindrew
Dies fehlten einige Fremdschlüssel auf einigen meiner Tabellen, während @LittleSweetSeas Antwort zeigte sie
Seafish
7

Wenn Sie im Objekt-Explorer-Fenster über SSMS wechseln möchten, klicken Sie mit der rechten Maustaste auf das Objekt, das Sie löschen möchten, und zeigen Sie Abhängigkeiten an.

Luis LL
quelle
7

Hier ist der beste Weg, um die Fremdschlüsselbeziehung in allen Datenbanken herauszufinden.

exec sp_helpconstraint 'Table Name'

und noch ein Weg

select * from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME='Table Name'
--and left(CONSTRAINT_NAME,2)='FK'(If you want single key)
Vinoth_S
quelle
Diese Lösung exec sp_helpconstraint 'Table Name'ist die einzige, die für mich überhaupt Zeilen zurückgibt. Der Name der Kontraint ist jedoch Kauderwelsch. PRIMARY KEY (clustered) PK__org_soft__3213E83FE6B07364
Tor
4
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;
Murali_DBA
quelle
1

- Das Folgende kann Ihnen mehr von dem geben, wonach Sie suchen:

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
Mike
quelle
1

Sie können auch alle Informationen über die Foreign KeysAntwort von @LittleSweetSeas zurückgeben:

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
user1
quelle
1

In SQL Server Management Studio können Sie einfach mit der rechten Maustaste auf die Tabelle im Objekt-Explorer klicken und "Abhängigkeiten anzeigen" auswählen. Dies würde Ihnen einen guten Ausgangspunkt geben. Es werden Tabellen, Ansichten und Prozeduren angezeigt, die auf die Tabelle verweisen.

Darrel Lee
quelle
0

Versuchen Sie die folgende Abfrage.

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

Dies gibt den Einschränkungsnamen, die Spaltennamen an, auf die verwiesen wird, und Tabellen, die von der Einschränkung abhängen, sind dort vorhanden.

Smart003
quelle
0

Mit dieser Abfrage können Sie Foreign keyKonstanten anzeigen :

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'

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

user1
quelle
0

Der einfachste Weg , um Primary Keyund Foreign Keyfür eine Tabelle ist:

/*  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'
Ashraf Abusada
quelle
0

Erweitern Sie im Objekt-Explorer die Tabelle und die Schlüssel:

Geben Sie hier die Bildbeschreibung ein

Hank Z.
quelle