Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

3 façons de renvoyer toutes les tables SANS clé primaire dans SQL Server

Si vous avez besoin de savoir si une base de données contient des tables qui n'ont pas de clé primaire, vous pouvez exécuter l'un des scripts suivants dans SQL Server pour renvoyer uniquement ces tables.

Tous ces scripts tirent parti de la OBJECTPROPERTY() une fonction. Cette fonction accepte une TableHasPrimaryKey argument que vous pouvez vérifier pour une valeur de 0 . Si c'est 0 , la table n'a pas de clé primaire. Si c'est 1 Cela fait. Par conséquent, vous pouvez également utiliser cette fonction pour renvoyer toutes les tables avec une clé primaire.

Ces scripts renvoient simplement le nom de la table et son schéma, mais vous pouvez toujours les modifier pour renvoyer plus de colonnes.

Option 1 - OBJECTPROPERTY() avec sys.tables

Les sys.tables La vue système est probablement le point de départ le plus évident. Cette vue renvoie une ligne pour chaque table utilisateur, et lorsque nous utilisons OBJECTPROPERTY() pour filtrer les résultats en fonction de TableHasPrimaryKey la propriété étant 0 , nous n'obtenons que ces tables sans clé primaire.

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

Résultat :

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

Dans ce cas, ma base de données actuelle est une base de données de test avec un tas de tables sans clés primaires.

Si j'exécute la même instruction sur une autre base de données, je n'obtiens aucun résultat :

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

Résultat :

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

Option 2 – OBJECTPROPERTY() avec INFORMATION_SCHEMA.TABLES

Cet exemple est similaire au précédent, sauf que cette fois j'interroge le INFORMATION_SCHEMA.TABLES voir. Les vues de schéma d'informations incluses dans SQL Server sont conformes à la définition standard ISO pour 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;

Résultat :

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() avec sys.objects

Dans cet exemple, j'interroge le sys.objects voir. Il s'agit d'une vue plus générale par rapport aux deux précédentes, et elle renvoie des informations sur les objets à portée de schéma (pas seulement les tables). Pour cette raison, nous devons filtrer les résultats en utilisant type = 'U' . Le U signifie ici table définie par l'utilisateur.

Encore une fois, nous pouvons utiliser le OBJECTPROPERTY() pour filtrer les résultats uniquement sur les tables qui n'ont pas de clé primaire.

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]

Résultat :

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

Nous pourrions également le filtrer par type_desc = 'USER_TABLE' , ce qui produirait le même résultat.

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]

Résultat :

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