sql >> Base de Datos >  >> RDS >> Sqlserver

7 formas de devolver todas las tablas con claves externas en SQL Server

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.