Come posso trovare tutte le tabelle in un DB che non hanno una chiave primaria esplicita?


10

Una ricerca di Google ha prodotto milioni di hit su come trovare tabelle senza cluster indicizzati, il PK normalmente è l'indice cluster di una tabella. Tuttavia, una tabella potrebbe facilmente avere una chiave naturale come indice cluster e un indice surrogato non cluster, come una colonna di identità.

Come posso trovare tutte le tabelle in un DB senza una chiave primaria definita? Ho 245 tabelle in questo DB: l'ispezione manuale è gravemente inefficiente.

Risposte:


13

Un paio di modi per abbellire questo gatto, ma funziona perfettamente in SQL Server 2005 e versioni successive e trovo che sia un modo semplice per gestire il problema:

La OBJECTPROPERTY()funzione può elencare varie proprietà su oggetti come tabelle. Una di queste proprietà è se una tabella ha o meno una chiave primaria.

OBJECTPROPERTY(object_id, tablehasprimarykey) = 0 sarebbe una tabella senza chiave primaria.

Così

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

Dovresti darti quello di cui hai bisogno. Puoi vedere tutto sugli altri modi per utilizzare la funzione OBJECTPROPERTY () nei libri online. Questa è la versione 2012 dell'articolo.


bene object_id funzionerà, ho pensato che stessimo usando la funzione, ma lo sys.tablesstesso dà l'id e grazie per aver mostrato questa meravigliosa funzione.
Biju jose,

Nessun problema. È una buona funzione da avere. Lotto di proprietà. In questo caso hai ragione - sys.tables elenca già object_id al suo interno. e questo è l'oggetto_id che vogliamo passare per il parametro ID alla funzione OBJECTPROPERTY. Grazie per la buona cattura della parola chiave riservata che ho usato lì :)
Mike Walsh,

, hai avuto esattamente ragione sulla funzione object_id, ho appena mischiato le cose lassù. Grazie per averlo sottolineato. Bene, objectproperty()è disponibile dal 2005 in poi, ho appena controllato Bol, giusto?
Biju jose,

Sì. Lì nel 2005-2014 e oltre a questo punto :-)
Mike Walsh,

Ho modificato lo script per aggiungere il nome dello schema. Si noti che (come OBJECTPROPERTY) la funzione OBJECT_SCHEMA_NAME () era una novità di MSSQL 2005.
Greenstone Walker,

5

La soluzione di Mike è eccellente per il problema specifico.

Se si desidera una maggiore flessibilità, ecco un'alternativa che può essere facilmente trasformato in una query che restituisce altre informazioni, come ad esempio trovare tutte le tabelle che sono cumuli, o la ricerca di tavoli che non hanno vincoli univoci a tutti .

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 volta che il tuo (sotto) sistema supera ~ 50 tabelle, è davvero importante familiarizzare con tutte le tabelle dei metadati, perché come hai detto, passare attraverso ogni tabella manualmente è impraticabile (e soggetto a errori!).


+1 per "perché, come hai detto, esaminare manualmente ogni tabella è impraticabile (e soggetto a errori!)." Amen lì. Molto incline all'errore :)
Mike Walsh,

4

La funzionalità di gestione dei criteri di SQL Server può eseguire alcune di queste operazioni.

Il facet della tabella ha i campi @HasIndex e @HasClusteredIndex (così come altri che possono essere utili, come i trigger). È possibile creare un criterio per verificare le condizioni su tutte le tabelle, in tutti i database, in un numero di server (utilizzando la funzione Central Management Server).

Tuttavia, non può verificare l'esistenza di un indice o vincolo di chiave primaria. Avrei giurato che c'era un campo @HasPrimaryKey ma non è presente in MSSQL2012. O sto ricordando male o sto impazzendo.

Nota: la gestione dei criteri è inclusa nelle edizioni SQL Server 2012 Enterprise, Business Intelligence e Standard. Non è disponibile nell'edizione Express.


2
Penso che potresti scrivere una condizione personalizzata che controlla questo. +1 per un modo completamente diverso di farlo.
Jon Seigel,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.