Comment puis-je savoir quelle contrainte FOREIGN KEY fait référence à une table dans SQL Server?

121

J'essaye de supprimer une table mais j'obtiens le message suivant:

Msg 3726, niveau 16, état 1, ligne 3
Impossible de supprimer l'objet 'dbo.UserProfile' car il est référencé par une contrainte FOREIGN KEY.
Msg 2714, niveau 16, état 6, ligne 2
Il existe déjà un objet nommé «UserProfile» dans la base de données.

J'ai regardé autour de moi avec SQL Server Management Studio mais je ne parviens pas à trouver la contrainte. Comment puis-je connaître les contraintes de clé étrangère?

marc_s
la source
2
J'aime sp_help 'dbo.TableName' Voir ici pour plus de moyens: stackoverflow.com/questions/483193/…
Mark Boltuc
2
Worth noticing:Answer by @LittleSweetSeas renverra des informations sur les clés étrangères POUR une table référencée donnée , cependant les détails de réponse de @ Gayathri-Varma pour une table parent donnée . Les deux sont utiles dans un contexte différent et gagnent tous les deux leur propre course :-)
Izhar Aazmi

Réponses:

225

C'est ici:

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'

De cette façon, vous obtiendrez la table de référence et le nom de la colonne.

Modifié pour utiliser sys.tables au lieu de sys.objects génériques selon la suggestion de commentaire. Merci, marc_s

LittleSweetSeas
la source
Vous devriez utiliser le plus concentré sys.tablesplutôt quesys.objects
marc_s
@marc_s: Merci, mais pourriez-vous poster un exemple? AFAIK dans sys.tables Je n'ai pas de références FK
LittleSweetSeas
3
Ce que je voulais dire: il suffit de le remplacer INNER JOIN sys.objects AS o ON o.OBJECT_ID = fc.referenced_object_idparINNER JOIN sys.tables t ON t.OBJECT_ID = fc.referenced_object_id
marc_s
@LittleSweetSeas j'avais exécuté la requête ci-dessus mais je n'obtiens toujours pas le nom de l'objet et le nom de la colonne pour la table qui avait une contrainte de clé étrangère
Smart003
Vous pouvez étoffer votre sélection avec un peu plus d'informations: 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_NAME (f.referenced_object) , COL_NAME (fc.referenced_object_id, fc.referenced_column_id) ReferencedColumn
DocOc
74

Une autre façon consiste à vérifier les résultats de

sp_help 'TableName'

(ou mettez simplement en surbrillance le TableName cité et appuyez sur ALT + F1)

Avec le temps, j'ai simplement décidé d'affiner ma réponse. Vous trouverez ci-dessous une capture d'écran des résultats sp_helpfournis. A ont utilisé la base de données AdventureWorksDW2012 pour cet exemple. Il y a de nombreuses bonnes informations là-bas, et ce que nous recherchons est à la toute fin - surligné en vert:

entrez la description de l'image ici

Vladislav
la source
3
+1 Cela donne beaucoup d'informations utiles et cela montre les clés étrangères au bas de la sortie
Hux
1
Cela me donne beaucoup d'informations dans le plus petit nombre de lignes de code
Rennish Joseph
C'est le raccourci le plus cool! Bat complètement Ctl-R pour rafraîchir le schéma!
M. Young
Actualiser le cache InteliSense local = Ctrl + Maj + R; Ctrl + R = afficher / masquer le volet des résultats (ou du moins ce sont mes valeurs par défaut pour SSMS2008 et SSMS2014)
Vladislav
44

Essaye ça

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
la source
1
Court et élégant, plus fonctionne pour moi! La seule chose est que la namevaleur renvoyée est un nom interne (méthinks), et non le nom de colonne réel dans la table parent. Aucun moyen de réparer cela?
Hamman Samuel
Ce que je vois ici, c'est que le ParentTableNameserait toujours le même que le donné ' Tablename' dans la clause where (si elle est incluse). Cela peut être intentionnel et sera plus utile en cas d'interrogation pour plusieurs tables.
Izhar Aazmi
28

J'ai trouvé cette réponse assez simple et j'ai fait le truc pour ce dont j'avais besoin: https://stackoverflow.com/a/12956348/652519

Un résumé du lien, utilisez cette requête:

EXEC sp_fkeys 'TableName'

Rapide et simple. J'ai pu localiser assez rapidement toutes les tables de clés étrangères, les colonnes respectives et les noms de clés étrangères de 15 tables.

Comme @mdisibio noté ci-dessous, voici un lien vers la documentation qui détaille les différents paramètres pouvant être utilisés: https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp- fkeys-transact-sql

Michael
la source
1
Il y a cinq autres paramètres sur lesquels filtrer, le plus utile à connaître est le second où vous pouvez spécifier un schéma autre que celui par défaut, par exempleEXEC sp_fkeys 'Payroll', 'accounting'
mdisibio
8

J'utilise ce script pour trouver tous les détails liés à la clé étrangère. J'utilise INFORMATION.SCHEMA. Voici un 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
Anvesh
la source
2
Je cherchais un moyen de voir les colonnes qui sont des clés étrangères et les tables associées auxquelles la colonne fait référence, et cela résume bien. Merci!
Nate Kindrew
Il manquait des clés étrangères sur certaines de mes tables alors que la réponse de @LittleSweetSeas leur montrait
Seafish
7

si vous voulez passer par SSMS dans la fenêtre de l'explorateur d'objets, faites un clic droit sur l'objet que vous souhaitez déposer, affichez les dépendances.

Luis LL
la source
7

Voici le meilleur moyen de découvrir la relation de clé étrangère dans toutes les bases de données.

exec sp_helpconstraint 'Table Name'

et encore une façon

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
la source
Cette solution exec sp_helpconstraint 'Table Name'est la seule qui renvoie des lignes pour moi. Cependant, le nom de la contraint est charabia. 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;
Murali_DBA
la source
1

- Ce qui suit peut vous donner plus de ce que vous recherchez:

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
la source
1

Vous pouvez également renvoyer toutes les informations sur la Foreign Keysréponse en adaptant la réponse @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
utilisateur1
la source
1

Dans SQL Server Management Studio, vous pouvez simplement cliquer avec le bouton droit sur la table dans l'explorateur d'objets et sélectionner "Afficher les dépendances". Cela vous donnerait un bon point de départ. Il affiche des tables, des vues et des procédures qui font référence à la table.

Darrel Lee
la source
0

essayez la requête suivante.

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

cela donnera le nom_contrainte, les noms_colonne qui feront référence et les tables qui dépendront de la contrainte seront là.

Smart003
la source
0

Vous pouvez utiliser cette requête pour afficher les Foreign keyconstaraints:

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'

Tiré de http://blog.sqlauthority.com/2006/11/01/sql-server-query-to-display-foreign-key-relationships-and-name-of-the-constraint-for-each-table- dans la base de données /

utilisateur1
la source
0

Le moyen le plus simple d'obtenir Primary Keyet Foreign Keypour une table est:

/*  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'
Achraf Abusada
la source
0

Dans l'Explorateur d'objets, développez le tableau et développez les clés:

entrez la description de l'image ici

Hank Z
la source