¿Cómo puedo averiguar qué restricción FOREIGN KEY hace referencia a una tabla en SQL Server?

121

Estoy tratando de soltar una mesa pero recibo el siguiente mensaje:

Msg 3726, nivel 16, estado 1, línea 3
No se pudo quitar el objeto 'dbo.UserProfile' porque hace referencia a una restricción FOREIGN KEY.
Msg 2714, nivel 16, estado 6, línea 2
Ya existe un objeto llamado 'UserProfile' en la base de datos.

Miré a mi alrededor con SQL Server Management Studio pero no puedo encontrar la restricción. ¿Cómo puedo averiguar las restricciones de clave externa?

marc_s
fuente
2
Me gusta sp_help 'dbo.TableName' Vea aquí para más formas: stackoverflow.com/questions/483193/…
Mark Boltuc
2
Worth noticing:La respuesta de @LittleSweetSeas devolverá información sobre las claves externas PARA una tabla referenciada determinada , sin embargo, los detalles de respuesta de @ Gayathri-Varma para una tabla principal determinada . Ambos son útiles en diferentes contextos y ambos ganan su propia carrera :-)
Izhar Aazmi

Respuestas:

225

Aquí está:

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 esta manera, obtendrá la tabla de referencia y el nombre de la columna.

Editado para usar sys.tables en lugar de sys.objects genéricos según la sugerencia de comentario. Gracias, marc_s

LittleSweetSeas
fuente
Se debe utilizar la más centrado sys.tablesen lugar desys.objects
marc_s
@marc_s: Gracias, pero ¿podrías publicar un ejemplo? AFAIK en sys.tables no tengo referencias de FK
LittleSweetSeas
3
Lo que quise decir: simplemente reemplácelo INNER JOIN sys.objects AS o ON o.OBJECT_ID = fc.referenced_object_idconINNER JOIN sys.tables t ON t.OBJECT_ID = fc.referenced_object_id
marc_s
@LittleSweetSeas había ejecutado la consulta anterior, pero todavía no obtengo el nombre de objeto y el nombre de la columna para la tabla que tenía una restricción de clave externa
Smart003
Puede reforzar su selección con un poco más de información: 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_dobject_id) , COL_NAME (fc.referenced_object_id, fc.referenced_column_id) ReferencedColumn
DocOc
74

Otra forma es comprobar los resultados de

sp_help 'TableName'

(o simplemente resalte el TableName citado y presione ALT + F1)

Con el paso del tiempo, decidí refinar mi respuesta. A continuación se muestra una captura de pantalla de los resultados que sp_helpproporciona. A han utilizado la base de datos AdventureWorksDW2012 para este ejemplo. Allí hay mucha información buena, y lo que estamos buscando está al final, resaltado en verde:

ingrese la descripción de la imagen aquí

Vladislav
fuente
3
+1 Esto proporciona mucha información útil y muestra claves externas en la parte inferior de la salida
Hux
1
Esto me da mucha información en la menor cantidad de líneas de código
Rennish Joseph
¡Este es el atajo más genial! ¡Supera completamente a Ctl-R para actualizar el esquema!
Mr. Young
Actualizar caché de InteliSense local = Ctrl + Shift + R; Ctrl + R = mostrar / ocultar el panel de resultados (o al menos estos son mis valores predeterminados para SSMS2008 y SSMS2014)
Vladislav
44

Prueba esto

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
fuente
1
Corto y elegante, ¡además funciona para mí! Lo único es que el namevalor devuelto es un nombre interno (creo), y no el nombre real de la columna en la tabla principal. Cualquier forma de arreglar esto?
Hamman Samuel
Lo que veo aquí es que ParentTableNamesiempre sería el mismo que el dado ' Tablename' en la cláusula where (si se incluye). Esto puede ser intencional y será más útil cuando se le solicite más de una tabla.
Izhar Aazmi
28

Encontré esta respuesta bastante simple e hice el truco para lo que necesitaba: https://stackoverflow.com/a/12956348/652519

Un resumen del enlace, use esta consulta:

EXEC sp_fkeys 'TableName'

Rápido y sencillo. Pude ubicar todas las tablas de claves externas, las columnas respectivas y los nombres de claves externas de 15 tablas con bastante rapidez.

Como @mdisibio señaló a continuación, aquí hay un enlace a la documentación que detalla los diferentes parámetros que se pueden usar: https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp- fkeys-transact-sql

Miguel
fuente
1
Hay otros cinco parámetros para filtrar, el más útil de los cuales conocer es el segundo en el que puede especificar un esquema no predeterminado, por ejemploEXEC sp_fkeys 'Payroll', 'accounting'
mdisibio
8

Estoy usando este script para encontrar todos los detalles relacionados con la clave externa. Estoy usando INFORMATION.SCHEMA. A continuación se muestra 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
fuente
2
Estaba buscando una forma de ver las columnas que son claves externas y las tablas relacionadas a las que hace referencia la columna, y esto lo resume muy bien. ¡Gracias!
Nate Kindrew
A esto le faltaban algunas claves externas en algunas de mis tablas, mientras que la respuesta de @LittleSweetSeas las mostraba
Seafish
7

si desea ir a través de SSMS en la ventana del explorador de objetos, haga clic con el botón derecho en el objeto que desea soltar, vea las dependencias.

Luis LL
fuente
7

Esta es la mejor manera de averiguar la relación de clave externa en toda la base de datos.

exec sp_helpconstraint 'Table Name'

y una forma mas

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
fuente
Esta solución exec sp_helpconstraint 'Table Name'es la única que me devuelve filas. Sin embargo, el nombre de la restricción es un galimatías. 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
fuente
1

- Lo siguiente puede darle más de lo que está buscando:

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
Miguel
fuente
1

También puede devolver toda la información sobre el Foreign Keysadaptando la respuesta de @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
usuario1
fuente
1

En SQL Server Management Studio, puede hacer clic derecho en la tabla en el explorador de objetos y seleccionar "Ver dependencias". Esto le daría un buen punto de partida. Muestra tablas, vistas y procedimientos que hacen referencia a la tabla.

Darrel Lee
fuente
0

prueba la siguiente consulta.

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

esto dará el nombre_restricción, los nombres_de_columna que serán de referencia y las tablas que dependerán de la restricción estarán allí.

Smart003
fuente
0

Puede utilizar esta consulta para mostrar 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'

Tomado de http://blog.sqlauthority.com/2006/11/01/sql-server-query-to-display-foreign-key-relationships-and-name-of-the-constraint-for-each-table- en la base de datos /

usuario1
fuente
0

La forma más fácil de obtener Primary Keyy Foreign Keypara una mesa es:

/*  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
fuente
0

En el Explorador de objetos, expanda la tabla y expanda las claves:

ingrese la descripción de la imagen aquí

Hank Z
fuente