Cet article propose sept façons de renvoyer toutes les tables qui ont des clés étrangères dans une base de données dans SQL Server.
Chaque table est retournée une seule fois, quel que soit le nombre de clés étrangères qu'elle peut avoir. Ceci est différent du retour de toutes les clés étrangères, ainsi que de leurs tables. Si vous souhaitez le faire, consultez 11 façons de renvoyer des clés étrangères dans SQL Server.
Tous les exemples ici interrogent la même base de données et renvoient donc le même résultat.
Option 1 - OBJECTPROPERTY() avec sys.tables
La première option consiste à utiliser le OBJECTPROPERTY()
fonction lors de l'interrogation de sys.tables
vue système.
Cette fonction accepte une TableHasForeignKey
argument, qui sera soit 1
ou 0
(ou NULL
). Si c'est 1
, cela signifie que la table possède une clé étrangère. Une valeur de 0
signifie qu'il n'a pas de clés étrangères. Par conséquent, nous pouvons l'utiliser dans un WHERE
clause pour renvoyer uniquement les tables où TableHasForeignKey
est défini sur 1
.
SELECT SCHEMA_NAME(schema_id) AS [Schema], name AS [Table] FROM sys.tables WHERE OBJECTPROPERTY(object_id, 'TableHasForeignKey') = 1 ORDER BY [Schema], [Table];
Résultat :
+----------+---------+ | Schema | Table | |----------+---------| | dbo | Albums | | dbo | Artists | +----------+---------+
Option 2 – OBJECTPROPERTY() avec INFORMATION_SCHEMA.TABLES
Cet exemple utilise OBJECTPROPERTY()
lors de l'interrogation de INFORMATION_SCHEMA.TABLES
vue système.
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE OBJECTPROPERTY(OBJECT_ID(CONCAT(TABLE_SCHEMA, '.', TABLE_NAME)),'TableHasForeignKey') = 1 AND TABLE_TYPE='BASE TABLE' ORDER BY TABLE_SCHEMA, TABLE_NAME;
Résultat :
+----------------+--------------+ | TABLE_SCHEMA | TABLE_NAME | |----------------+--------------| | dbo | Albums | | dbo | Artists | +----------------+--------------+
Option 3 - OBJECTPROPERTY() avec sys.objects
Voici encore une autre option qui utilise OBJECTPROPERTY()
. Cette fois, je l'utilise pour interroger le sys.objects
vue système.
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)), 'TableHasForeignKey') = 1 ORDER BY [Schema], [Table]
Résultat :
+----------+---------+ | Schema | Table | |----------+---------| | dbo | Albums | | dbo | Artists | +----------+---------+
Option 4 – INFORMATION_SCHEMA.TABLE_CONSTRAINTS avec DISTINCT
Voici un exemple qui interroge le INFORMATION_SCHEMA.TABLE_CONSTRAINTS
vue système où le type de contrainte est FOREIGN KEY
. Dans ce cas, j'utilise aussi le DISTINCT
clause afin d'empêcher les tables d'être retournées plus d'une fois lorsqu'elles ont plus d'une clé étrangère.
SELECT DISTINCT CONSTRAINT_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'FOREIGN KEY';
Résultat :
+---------------------+--------------+ | CONSTRAINT_SCHEMA | TABLE_NAME | |---------------------+--------------| | dbo | Albums | | dbo | Artists | +---------------------+--------------+
Voici ce qui se passe si je supprime le DISTINCT
clause :
SELECT CONSTRAINT_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'FOREIGN KEY';
Résultat :
+---------------------+--------------+ | CONSTRAINT_SCHEMA | TABLE_NAME | |---------------------+--------------| | dbo | Albums | | dbo | Albums | | dbo | Artists | +---------------------+--------------+
Dans ce cas, les Albums
table a deux clés étrangères, et j'obtiens donc deux lignes pour cette table.
Option 5 - sys.foreign_keys avec DISTINCT
Voici un autre exemple qui utilise le DISTINCT
clause, mais cette fois j'interroge le sys.foreign_keys
vue système.
SELECT DISTINCT OBJECT_SCHEMA_NAME(fk.parent_object_id) AS [Schema], OBJECT_NAME(fk.parent_object_id) AS [Table] FROM sys.foreign_keys AS fk ORDER BY [Schema], [Table];
Résultat :
+----------+---------+ | Schema | Table | |----------+---------| | dbo | Albums | | dbo | Artists | +----------+---------+
Et le voici sans le DISTINCT
clause :
SELECT OBJECT_SCHEMA_NAME(fk.parent_object_id) AS [Schema], OBJECT_NAME(fk.parent_object_id) AS [Table] FROM sys.foreign_keys AS fk ORDER BY [Schema], [Table];
Résultat :
+----------+---------+ | Schema | Table | |----------+---------| | dbo | Albums | | dbo | Albums | | dbo | Artists | +----------+---------+
Option 6 - sys.foreign_keys avec GROUP BY
Celui-ci est similaire à l'exemple précédent en ce sens qu'il interroge le sys.foreign_keys
vue système. La différence est que, plutôt que d'utiliser le DISTINCT
clause, elle utilise la clause GROUP BY
clause à la place.
SELECT OBJECT_SCHEMA_NAME(fk.parent_object_id) AS [Schema], OBJECT_NAME(fk.parent_object_id) AS [Table] FROM sys.foreign_keys AS fk GROUP BY OBJECT_SCHEMA_NAME(fk.parent_object_id), OBJECT_NAME(fk.parent_object_id);
Résultat :
+----------+---------+ | Schema | Table | |----------+---------| | dbo | Albums | | dbo | Artists | +----------+---------+
Option 7 - OBJECTPROPERTYEX()
Cet exemple pourrait doubler certains exemples précédents, mais il vaut toujours la peine d'être mentionné.
N'importe lequel des exemples précédents utilisant OBJECTPROPERTY()
fonction, pourrait facilement être réécrite pour utiliser le OBJECTPROPERTYEX()
une fonction. Cette fonction est essentiellement une extension de OBJECTPROPERTY()
, et il fait tout OBJECTPROPERTY()
fait et plus encore.
Je pourrais donc réécrire le premier exemple de cette page avec ce qui suit :
SELECT SCHEMA_NAME(schema_id) AS [Schema], name AS [Table] FROM sys.tables WHERE OBJECTPROPERTYEX(object_id, 'TableHasForeignKey') = 1 ORDER BY [Schema], [Table];
Résultat :
+----------+---------+ | Schema | Table | |----------+---------| | dbo | Albums | | dbo | Artists | +----------+---------+
Une différence que vous devez connaître est que ces deux fonctions renvoient des types de retour différents. OBJECTPROPERTY()
renvoie un int alors que OBJECTPROPERTYEX()
renvoie une sql_variant saisir.