sql >> Base de Datos >  >> RDS >> Sqlserver

Buscar dependencias en SQL Server:sql_expression_dependencies

En SQL Server, puede usar sys.sql_expression_dependencies vista de catálogo del sistema para devolver todas las dependencias en una entidad definida por el usuario en la base de datos actual. Esto incluye dependencias entre funciones escalares definidas por el usuario compiladas de forma nativa y otros módulos de SQL Server.

Puede usar esta vista para:

  • Devolver entidades que dependen de una determinada entidad
  • Devolver entidades de las que depende una determinada entidad

Entonces, por ejemplo, podría usarlo para devolver todos los objetos que hacen referencia a una tabla específica. También puede usarlo para devolver todos los objetos a los que hace referencia un procedimiento almacenado específico dentro de su código.

Específicamente, sys.sql_expression_dependencies ver información de dependencia de informes para las siguientes entidades:

  • Entidades vinculadas al esquema.
  • Entidades no vinculadas al esquema.
  • Entidades entre bases de datos y entre servidores. Se informan los nombres de las entidades; sin embargo, los ID de entidad no se resuelven.
  • Dependencias a nivel de columna en entidades vinculadas al esquema. Las dependencias de nivel de columna para objetos no vinculados al esquema se pueden devolver mediante sys.dm_sql_referenced_entities.
  • Disparadores DDL a nivel de servidor cuando se encuentra en el contexto de la base de datos maestra.

Ejemplo 1:todas las columnas devueltas

Aquí hay un ejemplo rápido que selecciona todas las columnas de sys.sql_expression_dependencies . Esto nos muestra qué datos se devuelven realmente en la vista, y podemos usar cualquiera de estas columnas en nuestras consultas para devolver solo los datos que nos interesan.

SELECT TOP(1) * 
FROM sys.sql_expression_dependencies;

Resultado (usando salida vertical):

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

Este ejemplo utiliza una salida vertical para que sea más fácil ver los nombres de las columnas sin tener que desplazarse horizontalmente. Por lo tanto, los nombres de las columnas se enumeran a la izquierda y sus respectivos valores a la derecha.

Además, en aras de la brevedad, utilicé TOP(1) para limitar los resultados a solo la primera fila.

Ejemplo 2:buscar entidades que dependan de una entidad

Para encontrar objetos que dependen de una entidad dada, use el referencing_id de esa entidad al seleccionar desde la vista.

Ejemplo:

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');

Resultado:

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

Aquí obtengo todas las entidades a las que se hace referencia en el uspGetClient procedimiento almacenado.

Aquí está la definición real de uspGetClient :

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

Entonces podemos ver que selecciona datos de una tabla llamada Client y acepta un argumento llamado @ClientCode con un tipo de datos (alias definido por el usuario) de clientcode .

Ejemplo 3:encontrar entidades de las que depende una entidad

También puede cambiarlo y obtener los objetos de los que depende una entidad determinada. Para hacer eso, use referenced_id (en lugar de referencing_id ) al seleccionar desde la vista.

Ejemplo:

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');

Resultado:

+----------------------+----------------------------+------------------+------------+
| 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 |
+----------------------+----------------------------+------------------+------------+

En este ejemplo, quería ver qué entidades dependen del Client tabla (es decir, qué entidades hacen referencia a esa tabla en su código SQL).

Notarás que también seleccioné diferentes columnas. Esto se debe a que estoy buscando información sobre las referencias entidad, no la referenciada entidad como en el ejemplo anterior.

Ejemplo 4:recuperar más información

Puede unir esta vista con otras vistas y/o tablas para obtener más información.

Por ejemplo, puedes unirlo con sys.objects para obtener el tipo de objeto de referencia:

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');

Resultado:

+----------------------+----------------------+----------+---------------------+------------+
| 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 |
+----------------------+----------------------+----------+---------------------+------------+

En este ejemplo también agregué COALESCE() función para devolver (n/a) siempre que referencing_minor_id es NULL . Esta función es una de las varias formas en que puede reemplazar un valor NULL con una cadena en SQL Server.

Ejemplo 5:entidades de bases de datos cruzadas y servidores cruzados

Como se mencionó, sql_expression_dependencies también funciona en entidades de bases de datos cruzadas y servidores cruzados. Sin embargo, en este caso, se informan los nombres de las entidades pero no se resuelven los ID de las entidades.

Este ejemplo usa exactamente el mismo código que el Ejemplo 2, excepto que esta vez es para una entidad diferente. Esta vez, quiero encontrar entidades que dependan 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');

Resultado:

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

En este ejemplo, el servidor al que se hace referencia y la base de datos a la que se hace referencia tienen un valor (en lugar de ser NULL como en el ejemplo anterior). Eso es porque el uspGetAlbumsByArtist El procedimiento almacenado usa un nombre de cuatro partes para hacer referencia a la entidad en un servidor vinculado (el procedimiento almacenado del ejemplo anterior no usaba un nombre de cuatro partes y tampoco usaba un nombre de tres partes para especificar la base de datos) .

En este ejemplo, Homer es el nombre del servidor vinculado y Music es la base de datos que consulta el procedimiento almacenado.

Podemos ver esto en uspGetAlbumsByArtist Definición de:

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

Documentación Oficial

Para obtener información más detallada y ejemplos, consulte sys.sql_expression_dependencies en el sitio web de Microsoft.

Aquí hay otro artículo de Microsoft que incluye instrucciones para obtener dependencias a través de SSMS.