Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

3 Möglichkeiten, alle Tabellen OHNE Primärschlüssel in SQL Server zurückzugeben

Wenn Sie jemals herausfinden müssen, ob eine Datenbank Tabellen ohne Primärschlüssel enthält, können Sie eines der folgenden Skripts in SQL Server ausführen, um nur diese Tabellen zurückzugeben.

Alle diese Skripte nutzen OBJECTPROPERTY() Funktion. Diese Funktion akzeptiert einen TableHasPrimaryKey Argument, das Sie auf den Wert 0 überprüfen können . Wenn es 0 ist , hat die Tabelle keinen Primärschlüssel. Wenn es 1 ist es tut. Daher können Sie diese Funktion auch verwenden, um alle Tabellen mit zurückzugeben ein Primärschlüssel.

Diese Skripte geben einfach den Namen der Tabelle und ihres Schemas zurück, aber Sie können sie jederzeit ändern, um mehr Spalten zurückzugeben.

Option 1 – OBJECTPROPERTY() mit sys.tables

Die sys.tables Die Systemansicht ist wahrscheinlich der naheliegendste Ausgangspunkt. Diese Ansicht gibt eine Zeile für jede Benutzertabelle zurück, und wenn wir OBJECTPROPERTY() verwenden um die Ergebnisse basierend auf dem TableHasPrimaryKey zu filtern Eigenschaft ist 0 , erhalten wir nur diese Tabellen ohne Primärschlüssel.

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

Ergebnis:

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 diesem Fall ist meine aktuelle Datenbank eine Testdatenbank mit einer Reihe von Tabellen ohne Primärschlüssel.

Wenn ich dieselbe Anweisung auf einer anderen Datenbank ausführe, erhalte ich keine Ergebnisse:

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

Ergebnis:

Changed database context to 'Music'.
(0 rows affected)

Option 2 – OBJECTPROPERTY() mit INFORMATION_SCHEMA.TABLES

Dieses Beispiel ähnelt dem vorherigen, außer dass ich diesmal INFORMATION_SCHEMA.TABLES abfrage Aussicht. Die in SQL Server enthaltenen Informationsschemaansichten entsprechen der ISO-Standarddefinition für das 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;

Ergebnis:

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)

Option 3 – OBJECTPROPERTY() mit sys.objects

In diesem Beispiel frage ich die sys.objects ab Aussicht. Dies ist eine allgemeinere Ansicht im Vergleich zu den beiden vorherigen und gibt Informationen zu schemabezogenen Objekten (nicht nur Tabellen) zurück. Aus diesem Grund müssen wir die Ergebnisse mit type = 'U' filtern . Das U hier steht für benutzerdefinierte Tabelle.

Auch hier können wir das OBJECTPROPERTY() verwenden Funktion, um die Ergebnisse nur auf die Tabellen zu filtern, die keinen Primärschlüssel haben.

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]

Ergebnis:

Changed database context to 'Test'.
+----------+--------------------+
| Schema   | Table              |
|----------+--------------------|
| dbo      | Datetime2Test      |
| dbo      | Datetime2Test2     |
| dbo      | DatetimeoffsetTest |
| dbo      | Individual         |
| dbo      | Occupation         |
| dbo      | Team               |
| dbo      | TimeTest           |
+----------+--------------------+
(7 rows affected)

Wir könnten alternativ nach type_desc = 'USER_TABLE' filtern , was zum gleichen Ergebnis führen würde.

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]

Ergebnis:

Changed database context to 'Test'.
+----------+--------------------+
| Schema   | Table              |
|----------+--------------------|
| dbo      | Datetime2Test      |
| dbo      | Datetime2Test2     |
| dbo      | DatetimeoffsetTest |
| dbo      | Individual         |
| dbo      | Occupation         |
| dbo      | Team               |
| dbo      | TimeTest           |
+----------+--------------------+
(7 rows affected)