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)