Come posso elencare tutte le chiavi esterne che fanno riferimento a una determinata tabella in SQL Server?


736

Devo rimuovere una tabella altamente referenziata in un database SQL Server. Come posso ottenere un elenco di tutti i vincoli di chiave esterna che dovrò rimuovere per eliminare la tabella?

(SQL risponde preferibilmente facendo clic su nella GUI di Management Studio.)


Per informazioni, vedi Come scrivere tutte le chiavi esterne di una tabella . Aggiornamento : il collegamento non è più disponibile ma l'SQL pertinente è stato copiato come risposta a una domanda correlata. È inoltre possibile visualizzare le dipendenze tramite la GUI.
Galiziano

Risposte:


1126

Non sono sicuro del motivo per cui nessuno ha suggerito, ma io uso sp_fkeysper interrogare le chiavi esterne per una determinata tabella:

EXEC sp_fkeys 'TableName'

Puoi anche specificare lo schema:

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

Senza specificare lo schema, i documenti indicano quanto segue:

Se non viene specificato pktable_owner, si applicano le regole di visibilità della tabella predefinite del DBMS sottostante.

In SQL Server, se l'utente corrente possiede una tabella con il nome specificato, vengono restituite le colonne di tale tabella. Se non viene specificato pktable_owner e l'utente corrente non possiede una tabella con pktable_name specificato, la procedura cerca una tabella con pktable_name specificato di proprietà del proprietario del database. Se ne esiste uno, vengono restituite le colonne di quella tabella.


41
Questo non funziona per me su un database sql 2008 per qualche motivo. sp_help mostra le relazioni, ma questo comando no.
tbone

21
@tbone: ho avuto lo stesso problema, che era legato alla non specifica completa dei parametri. Data la tabella T, di proprietà di O, nel database D è necessario eseguire EXEC sp_fkeys \ @ pktable_name = 'T', \ @ pktable_owner = 'O', \ @ pktable_qualifier = 'D' Prova a guardare l'output di EXEC sp_tables \ @ table_name = 'T' per capire quali dovrebbero essere i valori dei parametri.
Mads Ravn

3
@JustinRusso È possibile aggirare il problema creando una tabella, archiviando il risultato nella tabella, quindi selezionare le colonne specifiche. Dai un'occhiata a questo link per un esempio :).
John Odom,

3
Funziona bene in SSMS 2014. Grazie.
AH.

7
Ha già ricevuto risposta nei commenti precedenti: ma solo per chiarezza - EXEC sp_fkeys @pktable_name = N'Department ', @ pktable_owner = N'dbo'; msdn.microsoft.com/en-NZ/library/ms175090.aspx
Tejas Patel

233

Userei la funzionalità Diagrammi di database in SQL Server Management Studio, ma da quando l'hai escluso, questo ha funzionato per me in SQL Server 2008 (non ho 2005).

Per ottenere un elenco di nomi di tabelle e colonne di riferimento ...

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

Per ottenere nomi di vincoli di chiave esterna

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
ottimo, sebbene utilizzato referenced_object_id anziché parent. seleziona un nome distinto da sys.objects dove object_id in (seleziona fk.constraint_object_id da sys.foreign_key_columns come fk dove fk.referenced_object_id = (seleziona object_id da sys.tables dove name = 'tablename'))
chillitom

4
È possibile ottenere il nome di FK aggiungendo "nome_oggetto (nome_oggetto_oggetto)" alla selezione della prima query.
sam yi,

3
È possibile ottenere id oggetto object_id ('TableOthersForeignKeyInto')
IvanH

189

Questo ti dà:

  • L'FK stesso
  • Schema a cui appartiene l'FK
  • La " tabella di riferimento " o la tabella che ha l'FK
  • La " colonna di riferimento " o la colonna all'interno della tabella di riferimento che punta all'FK
  • La " tabella di riferimento " o la tabella con la colonna chiave a cui punta l'FK
  • La " colonna di riferimento " o la colonna che è la chiave a cui punta il tuo FK

Codice sotto:

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
Questa è la risposta migliore a mio parere se vuoi filtrare i risultati in seguito.
Faliorn,

Funziona alla grande! Sarebbe ancora meglio se: a) prefissi tutti i nomi delle colonne con "Fk" / "Chiave"), b) aggiungi tutti i nomi delle colonne con "Nome", c) rimuovi i caratteri di sottolineatura, d) aggiungi KeyTableSchemaName, e) aggiungi il valore predefinito order by: KeyTableSchemaName, KeyTableName, KeyColumnName, FkTableSchemaName, FkTableName, FkName e f) cambiano l'ordine delle colonne in: KeyTableSchemaName, KeyTableName, KeyColumnName, FkTableSchemaName, FkTableName, FkTableName / FkTableName / FkTableName / FkTableName / FkTableName / FkTableName convenzioni e d / e per l'uso più probabile (elencando i dipendenti FK di a Table).
Tom,

Una risposta così grande e una domanda utile. Grazie
Rich Dominelli

153

Prova questo :

sp_help 'TableName'

2
Bel metodo di supporto per sapere se stai esplorando il tuo db manualmente. Funziona anche su Azure SQL Server.
Pac0

48

Dovresti anche tenere conto dei riferimenti ad altri oggetti.

Se la tabella è stata fortemente referenziata da altre tabelle rispetto a quella probabilmente è anche fortemente referenziata da altri oggetti come viste, stored procedure, funzioni e altro.

Consiglio vivamente lo strumento GUI come la finestra di dialogo "Visualizza dipendenze" in SSMS o uno strumento gratuito come ApexSQL Cerca questo perché la ricerca di dipendenze in altri oggetti può essere soggetta a errori se vuoi farlo solo con SQL.

Se SQL è l'unica opzione, puoi provare a farlo in questo modo.

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

La domanda originale chiedeva di ottenere un elenco di tutte le chiavi esterne in una tabella con riferimenti elevati in modo che la tabella potesse essere rimossa.

Questa piccola query restituisce tutti i comandi 'drop chiave esterna' necessari per rilasciare tutte le chiavi esterne in una tabella particolare:

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'

Esempio di output:

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

Omettere la clausola WHERE per ottenere i comandi di rilascio per tutte le chiavi esterne nel database corrente.


17

Ecco il codice SQL che vorrei usare.

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

Non è SQL particolarmente chiaro, quindi diamo un'occhiata a un esempio.

Quindi, supponendo di voler eliminare la Employeestabella nell'amato Northwinddatabase di Microsoft , ma SQL Server mi ha detto che una o più chiavi esterne mi impedivano di farlo.

Il comando SQL sopra restituisce questi risultati ...

Chiavi esterne

Mi mostra che ci sono 3 chiavi esterne che fanno riferimento alla Employeestabella. In altre parole, non mi sarebbe permesso di eliminare (rilasciare) questa tabella fino a quando queste tre chiavi esterne non vengono eliminate per la prima volta.

Nei risultati, la prima riga indica come verrà mostrato il seguente vincolo di chiave esterna nei risultati.

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

La penultima colonna mostra il comando SQL che dovrei usare per cancellare una di queste chiavi esterne, ad esempio:

ALTER TABLE [Employees] DROP CONSTRAINT [FK_Employees_Employees]

... e la colonna di destra mostra l'SQL per crearlo ...

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

Con tutti questi comandi, hai tutto ciò che ti serve per eliminare le relative chiavi esterne per permetterti di eliminare una tabella, quindi ricrearle in seguito.

Uff. Spero che sia di aiuto.


Sarebbe più chiaro se si usassero le clausole di join interno e su anziché i cross join. Ma questo è stato utile comunque!
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

Il più semplice è usando sys.foreign_keys_columns in SQL. Qui la tabella contiene gli ID oggetto di tutte le chiavi esterne con l'ID colonna di riferimento ID tabella di riferimento nonché le colonne e le tabelle di riferimento. Poiché l'ID rimane costante, il risultato sarà affidabile per ulteriori modifiche nello schema e nelle tabelle.

Query:

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

Possiamo anche aggiungere filtri usando 'dove'

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

Questo è eccellente per quando è necessario rimuovere interi costrutti DB / set di tabelle di riferimento.
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

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


5

Alcune buone risposte sopra. Ma preferisco avere la risposta con una domanda. Questo pezzo di codice è tratto da sys.sp_helpconstraint (sys proc)

Questo è il modo in cui Microsoft cerca se ci sono chiavi esterne associate a tbl.

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

La risposta sarà simile alla seguente: test_db_name.dbo.Account: FK_Account_Customer


3
Questo è in realtà come 4 dichiarazioni di query separate ... questo fa effettivamente la stessa cosa in una frase: 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'

Se vuoi ottenere la relazione di chiave esterna di tutte le tabelle, escludi la whereclausola altrimenti scrivi il tuo tablename invece ditablename


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

Questo mostra la relazione solo se ci sono vincoli di chiave esterna. Apparentemente il mio database precede il vincolo FK.Alcune tabelle usano i trigger per imporre l'integrità referenziale, ea volte non c'è nient'altro che una colonna con nomi simili per indicare la relazione (e nessuna integrità referenziale).

Fortunatamente, abbiamo una scena di denominazione coerente, quindi sono in grado di trovare tabelle di riferimento e viste come questa:

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

Ho usato questa selezione come base per generare uno script che fa quello che devo fare nelle tabelle correlate.


3

Lavorando su quello che ha fatto @Gishu sono stato in grado di produrre e utilizzare il seguente SQL in SQL Server 2005

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;

Che visualizza le tabelle, le colonne e i nomi delle chiavi esterne in un'unica query.


3

Determinare chiavi primarie e chiavi univoche per tutte le tabelle in un database ...

Questo dovrebbe elencare tutti i vincoli e alla fine puoi mettere i tuoi filtri

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

Per riferimento, leggere attraverso: http://blogs.msdn.com/b/sqltips/archive/2005/09/16/469136.aspx


2
Questo contiene troppe informazioni per la domanda posta. Potresti includere qualche spiegazione (e rimuovere il codice extra) per rispondere alla domanda, per favore? Hai inviato questa risposta esatta a due domande diverse e ognuna necessita solo di una parte di questa risposta.
Andrew Barber,

2
Ho modificato la risposta - Determina le chiavi primarie e le chiavi univoche per tutte le tabelle in un database ... Penso che qui la risposta sia appropriata, perché la domanda è per tutti i riferimenti.
Dekdev,

3

Lo sto usando dal 2008 in poi. È simile ad alcune altre soluzioni elencate, ma i nomi dei campi vengono inseriti correttamente per gestire le regole di confronto specifiche per il caso (LatBin). Inoltre, puoi dargli un solo nome di tabella e recuperare solo le informazioni per quella tabella.

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

Ecco come contare tutte le responsabilità per l'ID selezionato. Basta cambiare il valore @dbTableName, il valore @dbRowId e il suo tipo (se int è necessario rimuovere '' nella riga n. 82 (..SET @SQL = ..)). Godere.

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

Il server Mysql ha una information_schema.REFERENTIAL_CONSTRAINTStabella FYI, puoi filtrarla in base al nome della tabella o al nome della tabella di riferimento.


2

Elenco di tutte le chiavi esterne che fanno riferimento a una determinata tabella in SQL Server:

È possibile ottenere il nome della tabella di riferimento e il nome della colonna tramite la seguente query ...

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'

E la seguente schermata per la tua comprensione ...

inserisci qui la descrizione dell'immagine


1

Questo ottiene qualsiasi chiave esterna che coinvolge la tabella scelta. * Presuppone un formato _FIRSTABLENAME_SECONDTABLENAME.

 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 )

Questa è una forma più generale:

 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

La seguente soluzione funziona per me:

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

Puoi trovare la query seguente:

 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

Prova anche.

EXEC sp_fkeys 'tableName', 'schemaName'

con sp_fkeyste puoi filtrare il risultato non solo con il nome e lo schema della tabella pk ma anche con il nome e lo schema della tabella fk. collegamento


0

Risposta più preferibile di @BankZ

sp_help 'TableName'   

inoltre per diversi schemi

sp_help 'schemaName.TableName'   
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.