Wie kann ich alle Fremdschlüssel auflisten, die auf eine bestimmte Tabelle in SQL Server verweisen?


736

Ich muss eine Tabelle mit hohem Verweis in einer SQL Server-Datenbank entfernen. Wie kann ich eine Liste aller Fremdschlüsseleinschränkungen erhalten, die ich entfernen muss, um die Tabelle zu löschen?

(SQL-Antworten sind dem Klicken in der GUI des Management Studios vorzuziehen.)


Weitere Informationen finden Sie unter Ausschreiben aller Fremdschlüssel einer Tabelle . Update : Link nicht mehr verfügbar, aber das relevante SQL wurde als Antwort auf eine verwandte Frage kopiert . Sie können Abhängigkeiten auch über die GUI anzeigen.
Galwegian

Antworten:


1126

Ich bin mir nicht sicher, warum niemand vorgeschlagen hat, aber ich sp_fkeysfrage Fremdschlüssel für eine bestimmte Tabelle ab:

EXEC sp_fkeys 'TableName'

Sie können auch das Schema angeben:

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

Ohne Angabe des Schemas geben die Dokumente Folgendes an:

Wenn pktable_owner nicht angegeben wird, gelten die Standardregeln für die Tabellensichtbarkeit des zugrunde liegenden DBMS.

Wenn der aktuelle Benutzer in SQL Server eine Tabelle mit dem angegebenen Namen besitzt, werden die Spalten dieser Tabelle zurückgegeben. Wenn pktable_owner nicht angegeben ist und der aktuelle Benutzer keine Tabelle mit dem angegebenen pktable_name besitzt, sucht die Prozedur nach einer Tabelle mit dem angegebenen pktable_name, der dem Datenbankeigentümer gehört. Wenn eine vorhanden ist, werden die Spalten dieser Tabelle zurückgegeben.


41
Dies funktioniert bei mir aus irgendeinem Grund in einer SQL 2008-Datenbank nicht. sp_help zeigt die Beziehungen an, dieser Befehl jedoch nicht.
Knochen

21
@tbone: Ich hatte das gleiche Problem, das damit zusammenhängt, dass die Parameter nicht vollständig angegeben wurden. Wenn die Tabelle T im Besitz von O ist, müssen Sie in Datenbank D EXEC sp_fkeys \ @ pktable_name = 'T', \ @ pktable_owner = 'O', \ @ pktable_qualifier = 'D' ausführen. Versuchen Sie, die Ausgabe von EXEC sp_tables \ @ zu betrachten. table_name = 'T', um herauszufinden, wie die Parameterwerte lauten sollten.
Mads Ravn

3
@JustinRusso Sie können dies umgehen, indem Sie eine Tabelle erstellen, das Ergebnis in der Tabelle speichern und dann die spezifischen Spalten auswählen. Schauen Sie sich diesen Link für ein Beispiel an :).
John Odom

3
Funktioniert gut in SSMS 2014. Danke.
AH.

7
Es wurde bereits in den obigen Kommentaren beantwortet: aber nur zur Klarheit - EXEC sp_fkeys @pktable_name = N'Department ', @ pktable_owner = N'dbo'; msdn.microsoft.com/en-NZ/library/ms175090.aspx
Tejas Patel

233

Ich würde die Funktion "Datenbankdiagramm" in SQL Server Management Studio verwenden, aber da Sie dies ausgeschlossen haben, hat dies in SQL Server 2008 für mich funktioniert (habe 2005 nicht).

Um eine Liste der verweisenden Tabellen- und Spaltennamen zu erhalten ...

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

Um Namen von Fremdschlüsseleinschränkungen zu erhalten

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
großartig, obwohl referenced_object_id anstelle von parent verwendet wird. Wählen Sie einen eindeutigen Namen aus sys.objects, in dem object_id in (wählen Sie fk.constraint_object_id aus sys.foreign_key_columns als fk aus, wobei fk.referenced_object_id = (wählen Sie object_id aus sys.tables aus, wobei name = 'tablename')
chillitom

4
Sie können den Namen von FK erhalten, indem Sie der Auswahl der ersten Abfrage "Objektname (Einschränkungsobjekt-ID)" hinzufügen.
Sam Yi

3
Sie können die Objekt-ID object_id ('TableOthersForeignKeyInto')
IvanH

189

Dies gibt Ihnen:

  • Die FK selbst
  • Schema, zu dem der FK gehört
  • Die " Referenzierungstabelle " oder die Tabelle mit der FK
  • Die " Referenzierungsspalte " " oder die Spalte in der Referenzierungstabelle, die auf die FK verweist
  • Die " referenzierte Tabelle " oder die Tabelle mit der Schlüsselspalte, auf die Ihr FK zeigt
  • Die " referenzierte Spalte " oder die Spalte, auf die Ihr FK verweist

Code unten:

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
Dies ist meiner Meinung nach die beste Antwort, wenn Sie die Ergebnisse anschließend filtern möchten.
Faliorn

Funktioniert super! Es wäre sogar noch besser, wenn Sie: a) allen Spaltennamen "Fk" / "Key" voranstellen, b) allen Spaltennamen "Name" hinzufügen, c) Unterstriche entfernen, d) KeyTableSchemaName hinzufügen, e) Standard hinzufügen order by: KeyTableSchemaName, KeyTableName, KeyColumnName, FkTableSchemaName, FkTableName, FkName und f) Ändern Sie die Spaltenreihenfolge in: KeyTableSchemaName, KeyTableName, KeyColumnName, FkTableSchemaName, FkTableName, FkTableSchemaName, FkTableName Konventionen und d / e für die wahrscheinlichste Verwendung (Auflistung der FK-Abhängigen von a Table).
Tom

So eine tolle Antwort und nützliche Frage. Vielen Dank
Rich Dominelli

153

Versuche dies :

sp_help 'TableName'

2
Gute Hilfsmethode, um zu wissen, ob Sie Ihre Datenbank manuell erkunden. Es funktioniert auch unter Azure SQL Server.
Pac0

48

Sie sollten auch die Verweise auf andere Objekte beachten.

Wenn die Tabelle von anderen Tabellen stark referenziert wurde, wird sie wahrscheinlich auch von anderen Objekten wie Ansichten, gespeicherten Prozeduren, Funktionen und mehr stark referenziert.

Ich würde wirklich ein GUI-Tool wie das Dialogfeld "Abhängigkeiten anzeigen" in SSMS oder ein kostenloses Tool wie ApexSQL Search empfehlen da die Suche nach Abhängigkeiten in anderen Objekten fehleranfällig sein kann, wenn Sie dies nur mit SQL tun möchten.

Wenn SQL die einzige Option ist, können Sie dies versuchen.

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

Bei der ursprünglichen Frage wurde darum gebeten, eine Liste aller Fremdschlüssel in eine Tabelle mit hohem Verweis aufzunehmen, damit die Tabelle entfernt werden kann.

Diese kleine Abfrage gibt alle Befehle zum Löschen von Fremdschlüsseln zurück, die zum Ablegen aller Fremdschlüssel in einer bestimmten Tabelle erforderlich sind:

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'

Beispielausgabe:

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

Lassen Sie die WHERE-Klausel weg, um die Drop-Befehle für alle Fremdschlüssel in der aktuellen Datenbank abzurufen.


17

Hier ist der SQL-Code, den ich verwenden würde.

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

Es ist nicht besonders klar, SQL, also schauen wir uns ein Beispiel an.

Angenommen, ich wollte die EmployeesTabelle in der beliebten NorthwindDatenbank von Microsoft ablegen , aber SQL Server sagte mir, dass ein oder mehrere Fremdschlüssel mich daran hinderten.

Der obige SQL-Befehl würde diese Ergebnisse zurückgeben ...

Fremdschlüssel

Es zeigt mir, dass es 3 Fremdschlüssel gibt, die auf die EmployeesTabelle verweisen . Mit anderen Worten, ich darf diese Tabelle erst löschen (löschen), wenn diese drei Fremdschlüssel zum ersten Mal gelöscht werden.

In den Ergebnissen wird in der ersten Zeile angegeben, wie die folgende Fremdschlüsseleinschränkung in den Ergebnissen angezeigt wird.

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

Die vorletzte Spalte zeigt den SQL-Befehl, den ich zum Löschen eines dieser Fremdschlüssel verwenden müsste , z.

ALTER TABLE [Employees] DROP CONSTRAINT [FK_Employees_Employees]

... und die rechte Spalte zeigt die SQL zum Erstellen ...

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

Mit all diesen Befehlen haben Sie alles, was Sie zum Löschen der relevanten Fremdschlüssel benötigen, damit Sie eine Tabelle löschen und später neu erstellen können.

Puh. Hoffe das hilft.


Es wäre klarer, wenn Sie Inner Join und On-Klauseln anstelle von Cross Joins verwenden würden. Aber das war trotzdem hilfreich!
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

Am einfachsten ist es, sys.foreign_keys_columns in SQL zu verwenden. Hier enthält die Tabelle die Objekt-IDs aller Fremdschlüssel für ihre referenzierte Spalten-ID. Referenzierte Tabellen-ID sowie die referenzierenden Spalten und Tabellen. Da die IDs konstant bleiben, ist das Ergebnis für weitere Änderungen im Schema sowie in den Tabellen zuverlässig.

Abfrage:

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

Wir können auch Filter hinzufügen, indem wir 'where' verwenden.

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

Dies ist hervorragend geeignet, wenn Sie ganze DB-Konstrukte / Sätze von referenzierten Tabellen entfernen müssen.
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

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


5

Einige gute Antworten oben. Aber ich möchte die Antwort lieber mit einer Frage haben. Dieser Code stammt aus sys.sp_helpconstraint (sys proc)

Auf diese Weise sucht Microsoft nach Fremdschlüsseln, die dem tbl zugeordnet sind.

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

Die Antwort sieht folgendermaßen aus: test_db_name.dbo.Account: FK_Account_Customer


3
Dies ist eigentlich wie 4 separate Abfrageanweisungen ... dies macht effektiv das gleiche in einer Anweisung: 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'

Wenn Sie die Fremdschlüsselbeziehung aller Tabellen erhalten möchten, schließen Sie die whereKlausel aus. Andernfalls schreiben Sie Ihren Tabellennamen anstelle vontablename


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

Dies zeigt die Beziehung nur an, wenn es sich um Fremdschlüsseleinschränkungen handelt. Meine Datenbank ist anscheinend älter als die FK-Einschränkung. Einige Tabellen verwenden Trigger, um die referenzielle Integrität zu erzwingen, und manchmal gibt es nur eine ähnlich benannte Spalte, um die Beziehung anzuzeigen (und überhaupt keine referenzielle Integrität).

Glücklicherweise haben wir eine konsistente Namensszene, sodass ich folgende Referenztabellen und Ansichten finden kann:

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

Ich habe diese Auswahl als Grundlage für die Generierung eines Skripts verwendet, das genau das tut, was ich für die zugehörigen Tabellen tun muss.


3

Nach dem, was @Gishu getan hat, konnte ich das folgende SQL in SQL Server 2005 erstellen und verwenden

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;

Welche Zeigt die Tabellen, Spalten und Fremdschlüsselnamen in einer Abfrage an.


3

Bestimmen Sie Primärschlüssel und eindeutige Schlüssel für alle Tabellen in einer Datenbank ...

Dies sollte alle Einschränkungen auflisten und am Ende können Sie Ihre Filter setzen

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

Als Referenz lesen Sie bitte - http://blogs.msdn.com/b/sqltips/archive/2005/09/16/469136.aspx


2
Dies enthält zu viele Informationen für die gestellte Frage. Könnten Sie bitte eine Erklärung hinzufügen (und den zusätzlichen Code entfernen), um nur die Frage zu beantworten? Sie haben genau diese Antwort auf zwei verschiedene Fragen gepostet, und jede benötigt nur einen Teil dieser Antwort.
Andrew Barber

2
Ich habe die Antwort bearbeitet - Primärschlüssel und eindeutige Schlüssel für alle Tabellen in einer Datenbank ermitteln ... Ich denke, hier ist die Antwort angemessen, da die Frage für alle Referenzen gilt.
Dekdev

3

Ich habe dies ab 2008 verwendet. Es ähnelt einigen anderen aufgelisteten Lösungen, aber die Feldnamen sind für Groß- und Kleinschreibung (LatBin) richtig sortiert. Darüber hinaus können Sie ihm einen einzelnen Tabellennamen geben und nur die Informationen für diese Tabelle abrufen.

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

Hier erfahren Sie, wie Sie alle Verantwortlichkeiten für die ausgewählte ID zählen. Ändern Sie einfach den Wert von @dbTableName, den Wert von @dbRowId und seinen Typ (wenn int '' in Zeile Nr. 82 entfernen muss (..SET @SQL = ..)). Genießen.

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-Server hat information_schema.REFERENTIAL_CONSTRAINTSTabelle FYI, Sie können es nach Tabellenname oder referenzierten Tabellennamen filtern.


2

Liste aller Fremdschlüssel, die auf eine bestimmte Tabelle in SQL Server verweisen:

Sie können den Namen der referenzierenden Tabelle und den Spaltennamen durch folgende Abfrage erhalten ...

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'

Und folgender Screenshot zum besseren Verständnis ...

Geben Sie hier die Bildbeschreibung ein


1

Dadurch werden alle Fremdschlüssel abgerufen, die die ausgewählte Tabelle betreffen. * Nimmt ein _FIRSTABLENAME_SECONDTABLENAME-Format an.

 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 )

Dies ist eine allgemeinere 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

Die folgende Lösung funktioniert für mich:

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

Sie können durch folgende Abfrage finden:

 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

Probiere auch.

EXEC sp_fkeys 'tableName', 'schemaName'

Mit können sp_fkeysSie das Ergebnis nicht nur nach dem Namen und dem Schema der pk-Tabelle, sondern auch nach dem Namen und dem Schema der fk-Tabelle filtern. Verknüpfung


0

Am meisten bevorzugte Antwort von @BankZ

sp_help 'TableName'   

zusätzlich für verschiedene schemata

sp_help 'schemaName.TableName'   
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.