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

7 façons de renvoyer toutes les tables avec des clés étrangères dans SQL Server

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.