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

Rechercher des dépendances dans SQL Server :sql_expression_dependencies

Dans SQL Server, vous pouvez utiliser les sys.sql_expression_dependencies vue du catalogue système pour renvoyer toutes les dépendances sur une entité définie par l'utilisateur dans la base de données actuelle. Cela inclut les dépendances entre les fonctions scalaires définies par l'utilisateur compilées en mode natif et d'autres modules SQL Server.

Vous pouvez utiliser cette vue pour :

  • Renvoyer les entités qui dépendent d'une entité donnée
  • Renvoyer les entités dont dépend une entité donnée

Ainsi, par exemple, vous pouvez l'utiliser pour renvoyer tous les objets qui référencent une table spécifique. Vous pouvez également l'utiliser pour renvoyer tous les objets auxquels une procédure stockée spécifique fait référence dans son code.

Plus précisément, les sys.sql_expression_dependencies afficher les informations de dépendance des rapports pour les entités suivantes :

  • Entités liées au schéma.
  • Entités non liées au schéma.
  • Entités inter-bases de données et inter-serveurs. Les noms d'entités sont signalés ; cependant, les ID d'entité ne sont pas résolus.
  • Dépendances au niveau des colonnes sur les entités liées au schéma. Les dépendances au niveau des colonnes pour les objets non liés au schéma peuvent être renvoyées à l'aide de sys.dm_sql_referenced_entities.
  • Le DDL au niveau du serveur se déclenche dans le contexte de la base de données principale.

Exemple 1 - Toutes les colonnes sont renvoyées

Voici un exemple rapide qui sélectionne toutes les colonnes de sys.sql_expression_dependencies . Cela nous montre quelles données sont réellement renvoyées dans la vue, et nous pouvons utiliser n'importe laquelle de ces colonnes dans nos requêtes afin de renvoyer uniquement les données qui nous intéressent.

SELECT TOP(1) * 
FROM sys.sql_expression_dependencies;

Résultat (en utilisant la sortie verticale) :

referencing_id            | 114099447
referencing_minor_id      | 0
referencing_class         | 1
referencing_class_desc    | OBJECT_OR_COLUMN
is_schema_bound_reference | 0
referenced_class          | 1
referenced_class_desc     | OBJECT_OR_COLUMN
referenced_server_name    | NULL
referenced_database_name  | NULL
referenced_schema_name    | dbo
referenced_entity_name    | Client
referenced_id             | 434100587
referenced_minor_id       | 0
is_caller_dependent       | 0
is_ambiguous              | 0

Cet exemple utilise une sortie verticale afin de faciliter la visualisation des noms de colonne sans avoir à faire défiler horizontalement. Par conséquent, les noms de colonne sont répertoriés à gauche et leurs valeurs respectives à droite.

Aussi, par souci de brièveté, j'ai utilisé TOP(1) pour limiter les résultats à la première ligne uniquement.

Exemple 2 - Rechercher des entités qui dépendent d'une entité

Pour trouver des objets qui dépendent d'une entité donnée, utilisez le referencing_id de cette entité lors de la sélection dans la vue.

Exemple :

SELECT
    referenced_server_name AS [Referenced Server],
    referenced_database_name AS [Referenced DB],
    referenced_schema_name AS [Referenced Schema],
    referenced_entity_name AS [Referenced Entity],
    referenced_class_desc AS [Referenced Entity Class] 
FROM sys.sql_expression_dependencies
WHERE referencing_id = OBJECT_ID('uspGetClient');

Résultat :

+---------------------+-----------------+---------------------+---------------------+---------------------------+
| Referenced Server   | Referenced DB   | Referenced Schema   | Referenced Entity   | Referenced Entity Class   |
|---------------------+-----------------+---------------------+---------------------+---------------------------|
| NULL                | NULL            | dbo                 | Client              | OBJECT_OR_COLUMN          |
| NULL                | NULL            | NULL                | clientcode          | TYPE                      |
+---------------------+-----------------+---------------------+---------------------+---------------------------+

Ici, j'obtiens toutes les entités référencées dans le uspGetClient procédure stockée.

Voici la définition réelle de uspGetClient :

CREATE PROCEDURE [dbo].[uspGetClient] @ClientCode clientcode AS
SELECT 
    FirstName,
    LastName
FROM [dbo].[Client]
WHERE ClientCode = @ClientCode;

Nous pouvons donc voir qu'il sélectionne les données d'une table appelée Client , et il accepte un argument appelé @ClientCode avec un type de données (alias défini par l'utilisateur) de clientcode .

Exemple 3 – Rechercher les entités dont dépend une entité

Vous pouvez également l'inverser et obtenir les objets dont dépend une entité donnée. Pour ce faire, utilisez referenced_id (au lieu de referencing_id ) lors de la sélection dans la vue.

Exemple :

SELECT
    OBJECT_NAME(referencing_id) AS [Referencing Entity],
    OBJECT_NAME(referencing_minor_id) AS [Referencing Minor Entity],
    referencing_class_desc AS [Class],
    COL_NAME(referenced_id, referenced_minor_id) AS [Column]
FROM sys.sql_expression_dependencies
WHERE referenced_id = OBJECT_ID('Client');

Résultat :

+----------------------+----------------------------+------------------+------------+
| Referencing Entity   | Referencing Minor Entity   | Class            | Column     |
|----------------------+----------------------------+------------------+------------|
| uspGetClient         | NULL                       | OBJECT_OR_COLUMN | NULL       |
| uspGetOrdersByClient | NULL                       | OBJECT_OR_COLUMN | NULL       |
| chkClientCode        | NULL                       | OBJECT_OR_COLUMN | ClientCode |
+----------------------+----------------------------+------------------+------------+

Dans cet exemple, je voulais voir quelles entités dépendent du Client table (c'est-à-dire quelles entités référencent cette table dans leur code SQL).

Vous remarquerez que j'ai également sélectionné différentes colonnes. C'est parce que je recherche des informations sur le référencement l'entité, pas l'référencée entité comme dans l'exemple précédent.

Exemple 4 - Récupérer plus d'informations

Vous pouvez joindre cette vue à d'autres vues et/ou tables pour renvoyer plus d'informations.

Par exemple, vous pouvez le joindre avec sys.objects pour obtenir le type de l'objet de référence :

SELECT OBJECT_NAME(referencing_id) AS [Referencing Entity],   
    o.type_desc AS [Type],   
    COALESCE(COL_NAME(referencing_id, referencing_minor_id), '(n/a)') AS [Column],
    referenced_entity_name AS [Referenced Entity],   
    COALESCE(COL_NAME(referenced_id, referenced_minor_id), '(n/a)') AS [Column]
FROM sys.sql_expression_dependencies AS sed  
INNER JOIN sys.objects AS o ON sed.referencing_id = o.object_id  
WHERE referenced_id = OBJECT_ID(N'Client');

Résultat :

+----------------------+----------------------+----------+---------------------+------------+
| Referencing Entity   | Type                 | Column   | Referenced Entity   | Column     |
|----------------------+----------------------+----------+---------------------+------------|
| uspGetClient         | SQL_STORED_PROCEDURE | (n/a)    | Client              | (n/a)      |
| uspGetOrdersByClient | SQL_STORED_PROCEDURE | (n/a)    | Client              | (n/a)      |
| chkClientCode        | CHECK_CONSTRAINT     | (n/a)    | Client              | ClientCode |
+----------------------+----------------------+----------+---------------------+------------+

Dans cet exemple, j'ai également ajouté le COALESCE() fonction pour retourner (n/a) chaque fois que referencing_minor_id est NULL . Cette fonction est l'une des nombreuses façons dont vous pouvez remplacer une valeur NULL par une chaîne dans SQL Server.

Exemple 5 – Entités inter-bases de données et inter-serveurs

Comme mentionné, sql_expression_dependencies fonctionne également sur des entités inter-bases de données et inter-serveurs. Cependant, dans ce cas, les noms d'entité sont signalés mais les ID d'entité ne sont pas résolus.

Cet exemple utilise exactement le même code que l'exemple 2, sauf que cette fois c'est pour une entité différente. Cette fois, je veux trouver des entités qui dépendent de uspGetAlbumsByArtist :

SELECT
    referenced_server_name AS [Referenced Server],
    referenced_database_name AS [Referenced DB],
    referenced_schema_name AS [Referenced Schema],
    referenced_entity_name AS [Referenced Entity],
    referenced_class_desc AS [Referenced Entity Class] 
FROM sys.sql_expression_dependencies
WHERE referencing_id = OBJECT_ID('uspGetAlbumsByArtist');

Résultat :

+---------------------+-----------------+---------------------+---------------------+---------------------------+
| Referenced Server   | Referenced DB   | Referenced Schema   | Referenced Entity   | Referenced Entity Class   |
|---------------------+-----------------+---------------------+---------------------+---------------------------|
| Homer               | Music           | dbo                 | Albums              | OBJECT_OR_COLUMN          |
+---------------------+-----------------+---------------------+---------------------+---------------------------+

Dans cet exemple, le serveur référencé et la base de données référencée ont une valeur (au lieu d'être NULL comme dans l'exemple précédent). C'est parce que le uspGetAlbumsByArtist la procédure stockée utilise un nom en quatre parties pour référencer l'entité sur un serveur lié (la procédure stockée de l'exemple précédent n'a pas utilisé un nom en quatre parties, et elle n'a pas non plus utilisé un nom en trois parties pour spécifier la base de données) .

Dans cet exemple, Homer est le nom du serveur lié, et Music est la base de données que la procédure stockée interroge.

Nous pouvons le voir dans uspGetAlbumsByArtist définition :

CREATE PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS
SELECT AlbumName
FROM [Homer].[Music].[dbo].[Albums]
WHERE ArtistId = @ArtistId;

Documentation officielle

Pour des informations plus détaillées et des exemples, consultez sys.sql_expression_dependencies sur le site Web de Microsoft.

Voici un autre article de Microsoft qui comprend des instructions pour obtenir des dépendances via SSMS.