Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Encontre dependências no SQL Server:sql_expression_dependencies


No SQL Server, você pode usar o sys.sql_expression_dependencies exibição do catálogo do sistema para retornar todas as dependências em uma entidade definida pelo usuário no banco de dados atual. Isso inclui dependências entre funções escalares definidas pelo usuário compiladas nativamente e outros módulos do SQL Server.

Você pode usar essa visualização para:
  • Entidades de retorno que dependem de uma determinada entidade
  • Entidades de retorno das quais uma determinada entidade depende

Por exemplo, você pode usá-lo para retornar todos os objetos que fazem referência a uma tabela específica. Você também pode usá-lo para retornar todos os objetos que um procedimento armazenado específico faz referência em seu código.



Especificamente, o sys.sql_expression_dependencies visualizar informações de dependência de relatórios para as seguintes entidades:
  • Entidades vinculadas ao esquema.
  • Entidades não vinculadas ao esquema.
  • Entidades entre bancos de dados e servidores cruzados. Os nomes das entidades são relatados; no entanto, os IDs de entidade não são resolvidos.
  • Dependências no nível da coluna em entidades vinculadas ao esquema. As dependências em nível de coluna para objetos não vinculados a esquema podem ser retornadas usando sys.dm_sql_referenced_entities.
  • O DDL no nível do servidor é acionado quando no contexto do banco de dados mestre.

Exemplo 1 – Todas as colunas retornadas


Aqui está um exemplo rápido que seleciona todas as colunas de sys.sql_expression_dependencies . Isso nos mostra quais dados são realmente retornados na exibição e podemos usar qualquer uma dessas colunas em nossas consultas para retornar apenas os dados nos quais estamos interessados.
SELECT TOP(1) * 
FROM sys.sql_expression_dependencies;

Resultado (usando saída 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 exemplo usa saída vertical para facilitar a visualização dos nomes das colunas sem precisar rolar horizontalmente. Portanto, os nomes das colunas são listados à esquerda e seus respectivos valores à direita.

Além disso, por uma questão de brevidade, usei TOP(1) para limitar os resultados apenas à primeira linha.

Exemplo 2 – Encontrar entidades que dependem de uma entidade


Para encontrar objetos que dependem de uma determinada entidade, use o referencing_id dessa entidade ao selecionar na visualização.

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

Aqui eu recebo todas as entidades que são referenciadas no uspGetClient procedimento armazenado.

Aqui está a definição real para uspGetClient :
CREATE PROCEDURE [dbo].[uspGetClient] @ClientCode clientcode AS
SELECT 
    FirstName,
    LastName
FROM [dbo].[Client]
WHERE ClientCode = @ClientCode;

Assim, podemos ver que ele seleciona dados de uma tabela chamada Client , e aceita um argumento chamado @ClientCode com um tipo de dados (alias definido pelo usuário) de clientcode .

Exemplo 3 – Encontrar entidades das quais uma entidade depende


Você também pode alterná-lo e obter os objetos dos quais uma determinada entidade depende. Para fazer isso, use referenced_id (em vez de referencing_id ) ao selecionar na exibição.

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

Neste exemplo eu queria ver quais entidades dependem do Client table (ou seja, quais entidades fazem referência a essa tabela em seu código SQL).

Você notará que também selecionei colunas diferentes. Isso ocorre porque estou procurando informações sobre a referência entidade, não a referenciada entidade como no exemplo anterior.

Exemplo 4 – Obter mais informações


Você pode unir essa visualização com outras visualizações e/ou tabelas para retornar mais informações.

Por exemplo, você pode juntá-lo com sys.objects para obter o tipo do objeto de referência:
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 |
+----------------------+----------------------+----------+---------------------+------------+

Neste exemplo eu também adicionei o COALESCE() função para retornar (n/a) sempre que referencing_minor_id é NULL . Essa função é uma das várias maneiras de substituir um valor NULL por uma string no SQL Server.

Exemplo 5 – Entidades entre bancos de dados e entre servidores


Como mencionado, sql_expression_dependencies também funciona em entidades entre bancos de dados e servidores cruzados. No entanto, nesse caso, os nomes das entidades são relatados, mas os IDs das entidades não são resolvidos.

Este exemplo usa exatamente o mesmo código do Exemplo 2, exceto que desta vez é para uma entidade diferente. Desta vez, quero encontrar entidades que dependam 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          |
+---------------------+-----------------+---------------------+---------------------+---------------------------+

Neste exemplo, o servidor referenciado e o banco de dados referenciado têm um valor (em vez de ser NULL como no exemplo anterior). Isso porque o uspGetAlbumsByArtist procedimento armazenado usa um nome de quatro partes para fazer referência à entidade em um servidor vinculado (o procedimento armazenado do exemplo anterior não usava um nome de quatro partes e também não usava um nome de três partes para especificar o banco de dados) .

Neste exemplo, Homer é o nome do servidor vinculado e Music é o banco de dados que o procedimento armazenado consulta.

Podemos ver isso em uspGetAlbumsByArtist definição de:
CREATE PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS
SELECT AlbumName
FROM [Homer].[Music].[dbo].[Albums]
WHERE ArtistId = @ArtistId;

Documentação oficial


Para obter informações e exemplos mais detalhados, consulte sys.sql_expression_dependencies no site da Microsoft.

Aqui está outro artigo da Microsoft que inclui instruções para obter dependências via SSMS.