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

3 formas de devolver todas las tablas SIN una clave principal en SQL Server

Si alguna vez necesita averiguar si una base de datos tiene tablas que no tienen una clave principal, puede ejecutar cualquiera de los siguientes scripts en SQL Server para devolver solo esas tablas.

Todos estos scripts aprovechan OBJECTPROPERTY() función. Esta función acepta una TableHasPrimaryKey argumento que puede comprobar para un valor de 0 . Si es 0 , la tabla no tiene una clave principal. Si es 1 lo hace. Por lo tanto, también puede usar esta función para devolver todas las tablas con una clave principal.

Estos scripts simplemente devuelven el nombre de la tabla y su esquema, pero siempre puede modificarlos para que devuelvan más columnas.

Opción 1:OBJECTPROPERTY() con sys.tables

Las sys.tables La vista del sistema es probablemente el lugar más obvio para comenzar. Esta vista devuelve una fila para cada tabla de usuario, y cuando usamos OBJECTPROPERTY() para filtrar los resultados según la TableHasPrimaryKey propiedad siendo 0 , obtenemos solo esas tablas sin una clave principal.

USE Test;
SELECT 
  SCHEMA_NAME(schema_id) AS [Schema], 
  name AS [Table]
FROM sys.tables
WHERE OBJECTPROPERTY(object_id, 'TableHasPrimaryKey') = 0
ORDER BY [Schema], [Table];

Resultado:

Changed database context to 'Test'.
+----------+--------------------+
| Schema   | Table              |
|----------+--------------------|
| dbo      | Datetime2Test      |
| dbo      | Datetime2Test2     |
| dbo      | DatetimeoffsetTest |
| dbo      | Individual         |
| dbo      | Occupation         |
| dbo      | Team               |
| dbo      | TimeTest           |
+----------+--------------------+
(7 rows affected)

En este caso, mi base de datos actual es una base de datos de prueba con varias tablas sin claves principales.

Si ejecuto la misma declaración en otra base de datos, no obtengo resultados:

USE Music;
SELECT 
  SCHEMA_NAME(schema_id) AS [Schema], 
  name AS [Table]
FROM sys.tables
WHERE OBJECTPROPERTY(object_id, 'TableHasPrimaryKey') = 0
ORDER BY [Schema], [Table];

Resultado:

Changed database context to 'Music'.
(0 rows affected)

Opción 2:OBJECTPROPERTY() con INFORMACION_ESQUEMA.TABLAS

Este ejemplo es similar al anterior, excepto que esta vez estoy consultando el INFORMATION_SCHEMA.TABLES vista. Las vistas del esquema de información incluidas en SQL Server cumplen con la definición estándar ISO para INFORMACION_ESQUEMA.

USE Test;
SELECT 
  TABLE_SCHEMA,
  TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE OBJECTPROPERTY(OBJECT_ID(CONCAT(TABLE_SCHEMA, '.', TABLE_NAME)),'TableHasPrimaryKey') = 0 AND
TABLE_TYPE='BASE TABLE'
ORDER BY TABLE_SCHEMA, TABLE_NAME;

Resultado:

Changed database context to 'Test'.
+----------------+--------------------+
| TABLE_SCHEMA   | TABLE_NAME         |
|----------------+--------------------|
| dbo            | Datetime2Test      |
| dbo            | Datetime2Test2     |
| dbo            | DatetimeoffsetTest |
| dbo            | Individual         |
| dbo            | Occupation         |
| dbo            | Team               |
| dbo            | TimeTest           |
+----------------+--------------------+
(7 rows affected)

Opción 3:OBJECTPROPERTY() con sys.objects

En este ejemplo, consulto el sys.objects vista. Esta es una vista más general en comparación con las dos anteriores y devuelve información sobre objetos del ámbito del esquema (no solo tablas). Debido a esto, necesitamos filtrar los resultados usando type = 'U' . La U aquí significa tabla definida por el usuario.

Nuevamente, podemos usar OBJECTPROPERTY() función para filtrar los resultados solo a aquellas tablas que no tienen una clave principal.

USE Test;
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)), 'TableHasPrimaryKey') = 0
ORDER BY [Schema], [Table]

Resultado:

Changed database context to 'Test'.
+----------+--------------------+
| Schema   | Table              |
|----------+--------------------|
| dbo      | Datetime2Test      |
| dbo      | Datetime2Test2     |
| dbo      | DatetimeoffsetTest |
| dbo      | Individual         |
| dbo      | Occupation         |
| dbo      | Team               |
| dbo      | TimeTest           |
+----------+--------------------+
(7 rows affected)

Alternativamente, podríamos filtrarlo por type_desc = 'USER_TABLE' , que produciría el mismo resultado.

USE Test;
SELECT 
  SCHEMA_NAME(schema_id) AS [Schema],
  name AS [Table]
FROM sys.objects 
WHERE type_desc = 'USER_TABLE'
AND OBJECTPROPERTY(OBJECT_ID(CONCAT(SCHEMA_NAME(schema_id), '.', name)), 'TableHasPrimaryKey') = 0
ORDER BY [Schema], [Table]

Resultado:

Changed database context to 'Test'.
+----------+--------------------+
| Schema   | Table              |
|----------+--------------------|
| dbo      | Datetime2Test      |
| dbo      | Datetime2Test2     |
| dbo      | DatetimeoffsetTest |
| dbo      | Individual         |
| dbo      | Occupation         |
| dbo      | Team               |
| dbo      | TimeTest           |
+----------+--------------------+
(7 rows affected)