Comment trouver toutes les tables d'une base de données qui n'ont pas de clé primaire explicite?

10

Une recherche Google a généré des millions de visites sur la façon de trouver des tables sans indexation en cluster, le PK étant normalement l'index en cluster d'une table. Cependant, une table peut facilement avoir une clé naturelle comme index cluster et un index de substitution non cluster, comme une colonne d'identité.

Comment puis-je trouver toutes les tables dans une base de données sans clé primaire définie? J'ai 245 tableaux dans ce DB: l'inspection manuelle est extrêmement inefficace.

ProfK
la source

Réponses:

13

Deux façons de dépouiller ce chat, mais cela fonctionne bien dans SQL Server 2005 et versions ultérieures, et je trouve que c'est un moyen sans douleur de gérer le problème -

La OBJECTPROPERTY()fonction peut répertorier diverses propriétés sur des tables de type objet. L'une de ces propriétés est de savoir si une table a ou non une clé primaire.

OBJECTPROPERTY(object_id, tablehasprimarykey) = 0 serait une table sans clé primaire.

Alors

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

Devrait vous donner ce dont vous avez besoin. Vous pouvez voir tout sur les autres façons d'utiliser la fonction OBJECTPROPERTY () dans les livres en ligne. Ceci est la version 2012 de l'article.

Mike Walsh
la source
bien le object_id fonctionnera Je pensais que nous utilisons la fonction. mais le sys.tableslui - même donne l'identifiant et merci d'avoir montré cette merveilleuse fonction.
Biju jose
Aucun problème. C'est une bonne fonction à avoir. Beaucoup de propriétés. Dans ce cas, vous avez raison - sys.tables répertorie déjà l'id_objet à l'intérieur. et c'est le object_id que nous voulons transmettre pour le paramètre ID à la fonction OBJECTPROPERTY. Merci pour la bonne prise sur le mot-clé réservé que j'ai utilisé là-bas :)
Mike Walsh
, vous aviez exactement raison sur la fonction object_id, je viens de mélanger les choses là-haut. merci de l'avoir signalé objectproperty().
Biju jose
Oui. Il y en 2005 - 2014 et au-delà à ce stade :-)
Mike Walsh
J'ai édité le script pour ajouter le nom du schéma. Notez que (comme OBJECTPROPERTY) la fonction OBJECT_SCHEMA_NAME () était nouvelle dans MSSQL 2005.
Greenstone Walker
5

La solution de Mike est excellente pour le problème spécifique.

Si vous voulez plus de flexibilité, voici une alternative qui peut être facilement transformé en une requête qui retourne d' autres informations, telles que trouver toutes les tables qui sont des tas, ou de trouver des tables dépourvues de contraintes uniques du tout .

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)
        );

Une fois que votre (sous-) système dépasse ~ 50 tables, il est vraiment important de vous familiariser avec toutes les tables de métadonnées, car comme vous l'avez dit, parcourir chaque table manuellement n'est pas pratique (et sujet à erreur!).

Jon Seigel
la source
+1 pour "car comme vous l'avez dit, parcourir chaque table manuellement n'est pas pratique (et sujet à erreur!)." Amen là. Très enclin à l'erreur :)
Mike Walsh
4

La fonctionnalité de gestion des stratégies de SQL Server peut effectuer certaines de ces opérations.

La facette Table contient les champs @HasIndex et @HasClusteredIndex (ainsi que d'autres qui peuvent être utiles, comme les déclencheurs). Une stratégie peut être créée pour vérifier les conditions sur toutes les tables, dans toutes les bases de données, sur un certain nombre de serveurs (à l'aide de la fonction Central Management Server).

Il ne peut cependant pas vérifier l'existence d'un index ou d'une contrainte de clé primaire. J'aurais juré qu'il y avait un champ @HasPrimaryKey mais il n'est pas là dans MSSQL2012. Soit je me souviens mal, soit je deviens fou.

Remarque: la gestion des stratégies est incluse dans les éditions SQL Server 2012 Enterprise, Business Intelligence et Standard. Il n'est pas disponible dans l'édition Express.

Marcheur de Greenstone
la source
2
Je pense que vous pourriez écrire une condition personnalisée qui vérifie cela. +1 pour une manière totalement différente de procéder.
Jon Seigel