una tipos tabla restricciones referencial primary primarias llaves llave integridad foreign foraneas foranea ejemplos ejemplo datos creada compuesta como agregar sql sql-server tsql

tipos - ¿Cómo puedo enumerar todas las claves foráneas que hacen referencia a una tabla dada en SQL Server?



primary key y foreign key ejemplos (21)

Necesito eliminar una tabla altamente referenciada en una base de datos de SQL Server. ¿Cómo puedo obtener una lista de todas las restricciones de clave externa que tendré que eliminar para eliminar la tabla?

(Las respuestas de SQL son preferibles al hacer clic en Acerca de en la GUI del estudio de administración).


Algunas buenas respuestas arriba. Pero prefiero tener la respuesta con una consulta. Este fragmento de código se toma de sys.sp_helpconstraint (sys proc)

Esa es la forma en que Microsoft busca si hay claves foráneas asociadas al 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 respuesta se verá así: test_db_name.dbo.Account: FK_Account_Customer


Aquí está el código SQL que usaría.

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

No es particularmente claro SQL, así que veamos un ejemplo.

Entonces, suponiendo que quisiera eliminar la tabla de Employees en la querida base de datos Northwind Microsoft, pero SQL Server me dijo que una o más Claves foráneas me impedían hacer esto.

El comando SQL anterior devolvería estos resultados ...

Me muestra que hay 3 claves foráneas que hacen referencia a la tabla Employees . En otras palabras, no se me permitiría eliminar (eliminar) esta tabla hasta que estas tres Claves externas se eliminen por primera vez.

En los resultados, la primera fila es cómo se mostraría la siguiente restricción de clave externa en los resultados.

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

La segunda a la última columna muestra el comando SQL que necesitaría usar para eliminar una de estas claves foráneas, por ejemplo:

ALTER TABLE [Employees] DROP CONSTRAINT [FK_Employees_Employees]

... y la columna de la derecha muestra el SQL para crearlo ...

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

Con todos estos comandos, tiene todo lo que necesita para eliminar las claves foráneas relevantes para permitirle eliminar una tabla y luego volver a crearlas.

Uf. Espero que esto ayude.


El más simple es usar sys.foreign_keys_columns en SQL. Aquí, la tabla contiene los ID de objeto de todas las claves foráneas con su ID de columna referenciada ID de tabla referenciada, así como las columnas y tablas de referencia. Como los Id permanecen constantes, el resultado será confiable para futuras modificaciones en el esquema y en las tablas.

Consulta:

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

También podemos agregar filtro usando ''donde''

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


Esto obtiene cualquier clave externa que involucra la tabla elegida. * Asume 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 )

Esta es una forma más general:

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


Esto te da:

  • El propio FK en sí.
  • Esquema al que pertenece el FK
  • La " tabla de referencia " o la tabla que tiene el FK
  • La " columna de referencia " o la columna dentro de la tabla de referencia que apunta al FK
  • La " tabla referenciada " o la tabla que tiene la columna clave a la que apunta su FK
  • La " columna referenciada " o la columna que es la clave a la que apunta su FK

Código abajo:

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


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


Hay cómo obtener el recuento de todas las responsabilidades para la identificación seleccionada. Simplemente cambie el valor de @dbTableName, el valor de @dbRowId y su tipo (si es necesario, debe eliminar '''' en la línea no 82 (..SET @SQL = ..)). Disfrutar.

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


He estado usando esto en 2008 y hasta Es similar a algunas otras soluciones enumeradas, pero los nombres de los campos son adecuados para manejar las intercalaciones de casos específicos (LatBin). Además, puede darle un solo nombre de tabla y recuperar solo la información de esa tabla.

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


La pregunta original solicitada para obtener una lista de todas las claves externas en una tabla altamente referenciada para que la tabla se pueda eliminar.

Esta pequeña consulta devuelve todos los comandos ''soltar clave externa'' necesarios para soltar todas las claves externas en una tabla particular:

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

Ejemplo de salida:

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

Omita la cláusula WHERE para obtener los comandos soltar para todas las claves externas en la base de datos actual.


La siguiente solución funciona para mí:

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


Prueba esto :

sp_help ''TableName''


También debe prestar atención a las referencias a otros objetos.

Si la tabla fue altamente referenciada por otras tablas, es probable que también sea altamente referenciada por otros objetos como vistas, procedimientos almacenados, funciones y más.

Realmente recomiendo una herramienta GUI como el cuadro de diálogo ''ver dependencias'' en SSMS o una herramienta gratuita como ApexSQL. Busque esto porque la búsqueda de dependencias en otros objetos puede ser propensa a errores si desea hacerlo solo con SQL.

Si SQL es la única opción, podrías intentar hacerlo así.

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


Trabajando con lo que hizo @Gishu, pude producir y usar el siguiente SQL en 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;

Que muestra los nombres de tablas, columnas y claves externas en una sola consulta.


Usaría la función de Diagramación de base de datos en SQL Server Management Studio, pero como lo descartó, esto funcionó para mí en SQL Server 2008 (no tengo 2005).

Para obtener la lista de nombres de tabla y columna de referencia ...

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

Para obtener nombres de restricciones de clave externa

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


primero

EXEC sp_fkeys ''Table'', ''Schema''

Luego usa NimbleText para jugar con tus resultados


Determine claves primarias y claves únicas para todas las tablas en una base de datos ...

Esto debería enumerar todas las restricciones y al final puedes poner tus filtros.

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

Para referencia, lea a través de http://blogs.msdn.com/b/sqltips/archive/2005/09/16/469136.aspx


No estoy seguro de por qué nadie sugirió, pero uso sp_fkeys para consultar claves externas para una tabla determinada:

EXEC sp_fkeys ''TableName''


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

Esto solo muestra la relación si son restricciones de clave externa. Mi base de datos aparentemente es anterior a la restricción FK. Algunas tablas usan los desencadenantes para imponer la integridad referencial, y a veces no hay nada más que una columna de nombre similar para indicar la relación (y no hay integridad referencial).

Afortunadamente, tenemos una escena de nomenclatura coherente, por lo que puedo encontrar tablas de referencia y vistas como esta:

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

Utilicé esta selección como base para generar un script; hace lo que necesito hacer en las tablas relacionadas.


SELECT object_name(parent_object_id), object_name(referenced_object_id), name FROM sys.foreign_keys WHERE parent_object_id = object_id(''Table Name'')


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

Si desea obtener la relación de clave externa de todas las tablas, excluya la cláusula where o escriba su nombre de tabla en lugar de nombre de tablename


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