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)