Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

3 modi per restituire tutte le tabelle SENZA una chiave primaria in SQL Server

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)