¿Cómo encuentro todas las tablas en un DB que no tienen clave primaria explícita?

10

Una búsqueda en Google arrojó millones de resultados sobre cómo encontrar tablas sin índice agrupado, siendo el PK normalmente el índice agrupado de una tabla. Sin embargo, una tabla podría tener fácilmente una clave natural como índice agrupado y un índice sustituto no agrupado, como una columna de identidad.

¿Cómo encuentro todas las tablas en una base de datos sin una clave primaria definida? Tengo 245 tablas en este DB: la inspección manual es muy ineficiente.

ProfK
fuente

Respuestas:

13

Hay un par de formas de pelar este gato, pero esto funciona bien en SQL Server 2005 y versiones posteriores, y creo que es una forma sencilla de manejar el problema:

La OBJECTPROPERTY()función puede enumerar varias propiedades sobre objetos, como tablas. Una de esas propiedades es si una tabla tiene o no una clave primaria.

OBJECTPROPERTY(object_id, tablehasprimarykey) = 0 sería una tabla sin una clave primaria.

Entonces

SELECT OBJECT_SCHEMA_NAME( object_id ) as SchemaName, name AS TableName
FROM sys.tables
WHERE OBJECTPROPERTY(object_id,'tablehasprimaryKey') = 0 
ORDER BY SchemaName, TableName ;

Debería darte lo que necesitas. Puede ver todo sobre las otras formas de usar la función OBJECTPROPERTY () en los libros en línea. Esta es la versión 2012 del artículo.

Mike Walsh
fuente
bueno, el object_id funcionará, pensé que estábamos usando la función. pero el sys.tablesmismo da la identificación y gracias por mostrar esta maravillosa función.
Biju jose
No hay problema. Es una buena función tener. Gran cantidad de propiedades. En este caso, tiene razón: sys.tables ya enumera el object_id dentro de él. y ese es el object_id que queremos pasar para el parámetro ID a la función OBJECTPROPERTY. Gracias por la buena captura de la palabra clave reservada que utilicé allí :)
Mike Walsh
, estabas exactamente en lo correcto acerca de la función object_id, simplemente mezclé cosas allí. Bueno, gracias por señalarlo. Bueno, el objectproperty()está disponible desde 2005 en adelante, acabo de comprobar bol, ¿verdad?
Biju jose
Si. Allí en 2005 - 2014 y más allá en este punto :-)
Mike Walsh
Edité el script para agregar el nombre del esquema. Tenga en cuenta que (como OBJECTPROPERTY) la función OBJECT_SCHEMA_NAME () era nueva en MSSQL 2005.
Greenstone Walker
5

La solución de Mike es excelente para el problema específico.

Si desea más flexibilidad, esto es una alternativa que puede ser fácilmente se transformó en una consulta que devuelve otra información, como la búsqueda de todas las tablas que son montones, o la búsqueda de tablas que no tienen restricciones únicas en absoluto .

SELECT
    OBJECT_SCHEMA_NAME(t.object_id) AS SchemaName,
    t.name AS TableName
    FROM sys.tables t
    WHERE
        NOT EXISTS
        (
            SELECT *
                FROM sys.indexes i
                WHERE
                    (i.object_id = t.object_id) AND
                    (i.is_primary_key = 1)
        );

Una vez que su (sub) sistema supera las ~ 50 tablas, es realmente importante familiarizarse con todas las tablas de metadatos, porque como usted dijo, revisar cada tabla manualmente no es práctico (¡y propenso a errores!).

Jon Seigel
fuente
+1 para "porque, como dijiste, pasar por cada tabla manualmente no es práctico (¡y propenso a errores!"). Amén allí. Muy propenso al error :)
Mike Walsh
4

La función de administración de políticas de SQL Server puede hacer algo de esto.

La faceta Tabla tiene campos @HasIndex y @HasClusteredIndex (así como otros que pueden ser útiles, como los desencadenantes). Se puede crear una política para verificar las condiciones en todas las tablas, en todas las bases de datos, en varios servidores (utilizando la función Servidor de administración central).

Sin embargo, no puede verificar la existencia de un índice o restricción de clave primaria. Hubiera jurado que había un campo @HasPrimaryKey pero no está allí en MSSQL2012. Estoy recordando mal o me estoy volviendo loco.

Nota: La gestión de políticas se incluye con las ediciones SQL Server 2012 Enterprise, Business Intelligence y Standard. No está disponible en la edición Express.

Caminante de piedra verde
fuente
2
Creo que podría escribir una condición personalizada que verifique esto. +1 para una forma totalmente diferente de hacer esto.
Jon Seigel