Este artículo ofrece siete formas de devolver todas las tablas que tienen claves externas en una base de datos en SQL Server.
Cada tabla se devuelve una sola vez, independientemente de cuántas claves foráneas pueda tener. Esto es diferente a devolver todas las claves foráneas, junto con sus tablas. Si desea hacerlo, consulte 11 formas de devolver claves externas en SQL Server.
Todos los ejemplos aquí consultan la misma base de datos y, por lo tanto, devuelven el mismo resultado.
Opción 1:OBJECTPROPERTY() con sys.tables
La primera opción es usar OBJECTPROPERTY()
función al consultar el sys.tables
vista del sistema.
Esta función acepta una TableHasForeignKey
argumento, que será 1
o 0
(o NULL
). Si es 1
, esto significa que la tabla tiene una clave externa. Un valor de 0
significa que no tiene claves foráneas. Por lo tanto, podemos usar esto en un WHERE
cláusula para devolver solo aquellas tablas donde TableHasForeignKey
se establece en 1
.
SELECT SCHEMA_NAME(schema_id) AS [Schema], name AS [Table] FROM sys.tables WHERE OBJECTPROPERTY(object_id, 'TableHasForeignKey') = 1 ORDER BY [Schema], [Table];
Resultado:
+----------+---------+ | Schema | Table | |----------+---------| | dbo | Albums | | dbo | Artists | +----------+---------+
Opción 2:OBJECTPROPERTY() con INFORMACION_ESQUEMA.TABLAS
Este ejemplo usa OBJECTPROPERTY()
al consultar el INFORMATION_SCHEMA.TABLES
vista del sistema.
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE OBJECTPROPERTY(OBJECT_ID(CONCAT(TABLE_SCHEMA, '.', TABLE_NAME)),'TableHasForeignKey') = 1 AND TABLE_TYPE='BASE TABLE' ORDER BY TABLE_SCHEMA, TABLE_NAME;
Resultado:
+----------------+--------------+ | TABLE_SCHEMA | TABLE_NAME | |----------------+--------------| | dbo | Albums | | dbo | Artists | +----------------+--------------+
Opción 3:OBJECTPROPERTY() con sys.objects
Aquí hay otra opción más que usa OBJECTPROPERTY()
. Esta vez lo uso cuando consulto sys.objects
vista del sistema.
SELECT SCHEMA_NAME(schema_id) AS [Schema], name AS [Table] FROM sys.objects WHERE type = 'U' AND OBJECTPROPERTY(OBJECT_ID(CONCAT(SCHEMA_NAME(schema_id), '.', name)), 'TableHasForeignKey') = 1 ORDER BY [Schema], [Table]
Resultado:
+----------+---------+ | Schema | Table | |----------+---------| | dbo | Albums | | dbo | Artists | +----------+---------+
Opción 4:INFORMACION_ESQUEMA.TABLE_CONSTRAINTS con DISTINTO
Aquí hay un ejemplo que consulta el INFORMATION_SCHEMA.TABLE_CONSTRAINTS
vista del sistema donde el tipo de restricción es FOREIGN KEY
. En este caso, también uso el DISTINCT
cláusula para evitar que las tablas se devuelvan más de una vez cuando tienen más de una clave externa.
SELECT DISTINCT CONSTRAINT_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'FOREIGN KEY';
Resultado:
+---------------------+--------------+ | CONSTRAINT_SCHEMA | TABLE_NAME | |---------------------+--------------| | dbo | Albums | | dbo | Artists | +---------------------+--------------+
Esto es lo que sucede si elimino DISTINCT
cláusula:
SELECT CONSTRAINT_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'FOREIGN KEY';
Resultado:
+---------------------+--------------+ | CONSTRAINT_SCHEMA | TABLE_NAME | |---------------------+--------------| | dbo | Albums | | dbo | Albums | | dbo | Artists | +---------------------+--------------+
En este caso, los Albums
la tabla tiene dos claves foráneas, por lo que obtengo dos filas para esa tabla.
Opción 5:sys.foreign_keys con DISTINCT
Aquí hay otro ejemplo que usa DISTINCT
cláusula, pero esta vez estoy consultando el sys.foreign_keys
vista del sistema.
SELECT DISTINCT OBJECT_SCHEMA_NAME(fk.parent_object_id) AS [Schema], OBJECT_NAME(fk.parent_object_id) AS [Table] FROM sys.foreign_keys AS fk ORDER BY [Schema], [Table];
Resultado:
+----------+---------+ | Schema | Table | |----------+---------| | dbo | Albums | | dbo | Artists | +----------+---------+
Y aquí está sin el DISTINCT
cláusula:
SELECT OBJECT_SCHEMA_NAME(fk.parent_object_id) AS [Schema], OBJECT_NAME(fk.parent_object_id) AS [Table] FROM sys.foreign_keys AS fk ORDER BY [Schema], [Table];
Resultado:
+----------+---------+ | Schema | Table | |----------+---------| | dbo | Albums | | dbo | Albums | | dbo | Artists | +----------+---------+
Opción 6:sys.foreign_keys con GROUP BY
Este es similar al ejemplo anterior en que consulta el sys.foreign_keys
vista del sistema. La diferencia es que, en lugar de usar DISTINCT
cláusula, utiliza la cláusula GROUP BY
cláusula en su lugar.
SELECT OBJECT_SCHEMA_NAME(fk.parent_object_id) AS [Schema], OBJECT_NAME(fk.parent_object_id) AS [Table] FROM sys.foreign_keys AS fk GROUP BY OBJECT_SCHEMA_NAME(fk.parent_object_id), OBJECT_NAME(fk.parent_object_id);
Resultado:
+----------+---------+ | Schema | Table | |----------+---------| | dbo | Albums | | dbo | Artists | +----------+---------+
Opción 7:OBJETOPROPIEDADEX()
Este ejemplo podría duplicar algunos ejemplos anteriores, pero aún así vale la pena mencionarlo.
Cualquiera de los ejemplos anteriores que usan OBJECTPROPERTY()
función, podría reescribirse fácilmente para usar OBJECTPROPERTYEX()
función. Esta función es básicamente una extensión de OBJECTPROPERTY()
, y hace todo OBJECTPROPERTY()
hace y más.
Entonces podría reescribir el primer ejemplo en esta página con lo siguiente:
SELECT SCHEMA_NAME(schema_id) AS [Schema], name AS [Table] FROM sys.tables WHERE OBJECTPROPERTYEX(object_id, 'TableHasForeignKey') = 1 ORDER BY [Schema], [Table];
Resultado:
+----------+---------+ | Schema | Table | |----------+---------| | dbo | Albums | | dbo | Artists | +----------+---------+
Una diferencia que debe conocer es que estas dos funciones devuelven diferentes tipos de devolución. OBJECTPROPERTY()
devuelve un int mientras que OBJECTPROPERTYEX()
devuelve una sql_variant tipo.