Se hai bisogno di scoprire se un database ha tabelle che non hanno una chiave primaria, puoi eseguire uno dei seguenti script in SQL Server per restituire solo quelle tabelle.
Tutti questi script sfruttano OBJECTPROPERTY()
funzione. Questa funzione accetta un TableHasPrimaryKey
argomento che puoi verificare per un valore di 0
. Se è 0
, la tabella non ha una chiave primaria. Se è 1
lo fa. Pertanto, puoi anche usare questa funzione per restituire tutte le tabelle con una chiave primaria.
Questi script restituiscono semplicemente il nome della tabella e il suo schema, ma puoi sempre modificarli per restituire più colonne.
Opzione 1 – OBJECTPROPERTY() con sys.tables
Le sys.tables
la vista di sistema è probabilmente il punto di partenza più ovvio. Questa vista restituisce una riga per ogni tabella utente e quando utilizziamo OBJECTPROPERTY()
per filtrare i risultati in base a TableHasPrimaryKey
proprietà essendo 0
, otteniamo solo quelle tabelle senza una chiave primaria.
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];
Risultato:
Changed database context to 'Test'. +----------+--------------------+ | Schema | Table | |----------+--------------------| | dbo | Datetime2Test | | dbo | Datetime2Test2 | | dbo | DatetimeoffsetTest | | dbo | Individual | | dbo | Occupation | | dbo | Team | | dbo | TimeTest | +----------+--------------------+ (7 rows affected)
In questo caso, il mio attuale database è un database di prova con un mucchio di tabelle senza chiavi primarie.
Se eseguo la stessa istruzione su un altro database, non ottengo risultati:
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];
Risultato:
Changed database context to 'Music'. (0 rows affected)
Opzione 2 – OBJECTPROPERTY() con INFORMATION_SCHEMA.TABLES
Questo esempio è simile al precedente, tranne che questa volta sto interrogando il INFORMATION_SCHEMA.TABLES
Visualizza. Le viste dello schema di informazioni incluse in SQL Server sono conformi alla definizione standard ISO per INFORMATION_SCHEMA.
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;
Risultato:
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)
Opzione 3 – OBJECTPROPERTY() con sys.objects
In questo esempio, interrogo sys.objects
Visualizza. Questa è una visualizzazione più generale rispetto alle due precedenti e restituisce informazioni sugli oggetti con ambito schema (non solo sulle tabelle). Per questo motivo, dobbiamo filtrare i risultati usando type = 'U'
. Il U
qui sta per tabella definita dall'utente.
Ancora una volta, possiamo usare OBJECTPROPERTY()
funzione per filtrare i risultati solo in quelle tabelle che non hanno una chiave primaria.
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]
Risultato:
Changed database context to 'Test'. +----------+--------------------+ | Schema | Table | |----------+--------------------| | dbo | Datetime2Test | | dbo | Datetime2Test2 | | dbo | DatetimeoffsetTest | | dbo | Individual | | dbo | Occupation | | dbo | Team | | dbo | TimeTest | +----------+--------------------+ (7 rows affected)
In alternativa potremmo filtrarlo per type_desc = 'USER_TABLE'
, che produrrebbe lo stesso risultato.
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]
Risultato:
Changed database context to 'Test'. +----------+--------------------+ | Schema | Table | |----------+--------------------| | dbo | Datetime2Test | | dbo | Datetime2Test2 | | dbo | DatetimeoffsetTest | | dbo | Individual | | dbo | Occupation | | dbo | Team | | dbo | TimeTest | +----------+--------------------+ (7 rows affected)