No SQL Server, você pode usar o
sys.dm_sql_referenced_entities()
função de gerenciamento dinâmico do sistema para obter uma lista de todas as entidades definidas pelo usuário que são referenciadas por nome, na definição de uma determinada entidade. Em outras palavras, ele retorna uma lista de todas as entidades definidas pelo usuário das quais uma entidade específica depende.
Especificamente, ele relata os seguintes tipos de entidade referenciados pela entidade de referência especificada:
- Entidades vinculadas ao esquema
- Entidades não vinculadas a esquema
- Entidades entre bancos de dados e entre servidores
- Dependências em nível de coluna em entidades vinculadas e não vinculadas a esquema
- Tipos definidos pelo usuário (alias e CLR UDT)
- Coleções de esquema XML
- Funções de partição
Sintaxe
A sintaxe fica assim:
sys.dm_sql_referenced_entities ( ' [ schema_name. ] referencing_entity_name ' , '' ) ::= { OBJECT | DATABASE_DDL_TRIGGER | SERVER_DDL_TRIGGER }
Exemplo 1 – Exemplo básico
Segue um exemplo de uso:
USE Test; SELECT referenced_schema_name AS [Schema], referenced_entity_name AS Entity, referenced_minor_name AS Minor, referenced_class_desc AS Class, is_select_all, is_all_columns_found FROM sys.dm_sql_referenced_entities ( 'dbo.uspGetClient', 'OBJECT');
Resultado:
+----------+------------+------------+------------------+-----------------+------------------------+ | Schema | Entity | Minor | Class | is_select_all | is_all_columns_found | |----------+------------+------------+------------------+-----------------+------------------------| | dbo | Client | NULL | OBJECT_OR_COLUMN | 1 | 1 | | dbo | Client | ClientCode | OBJECT_OR_COLUMN | 1 | 1 | | dbo | Client | FirstName | OBJECT_OR_COLUMN | 1 | 1 | | dbo | Client | LastName | OBJECT_OR_COLUMN | 1 | 1 | | NULL | clientcode | NULL | TYPE | 0 | 0 | +----------+------------+------------+------------------+-----------------+------------------------+
Aqui eu recebo todas as entidades que são referenciadas no
dbo.uspGetClient
procedimento armazenado. Neste caso, existem cinco entidades. A primeira é a tabela chamada “Cliente”. As próximas três são todas as colunas dessa tabela. O último é um tipo de dados de alias definido pelo usuário chamado “clientcode”.
Também podemos ver que os quatro primeiros são usados em uma instrução select que usa o asterisco (
*
) curinga para selecionar todas as colunas (porque seu is_select_all
está definido como 1
). Aqui está a definição real usada para criar o procedimento armazenado que estamos analisando:
CREATE PROCEDURE [dbo].[uspGetClient] @ClientCode clientcode AS SELECT * FROM [dbo].[Client] WHERE ClientCode = @ClientCode;
Sim, é um procedimento armazenado muito simples, mas é ideal para nossos propósitos. Podemos ver todas as entidades referenciadas como retornadas por
sys.dm_sql_referenced_entities()
. Também podemos ver que o procedimento consiste em um único
SELECT
consulta que usa o curinga asterisco para selecionar todas as colunas. Exemplo 2 – Remova a opção “Selecionar tudo” (*
)
Vamos alterar o procedimento armazenado para que ele não use o curinga asterisco para selecionar todas as colunas.
ALTER PROCEDURE [dbo].[uspGetClient] @ClientCode clientcode AS SELECT FirstName, LastName FROM [dbo].[Client] WHERE ClientCode = @ClientCode;
Portanto, agora ele retorna explicitamente as colunas “FirstName” e “LastName”. Nenhum curinga encontrado.
Agora execute
sys.dm_sql_referenced_entities()
novamente:USE Test; SELECT referenced_schema_name AS [Schema], referenced_entity_name AS Entity, referenced_minor_name AS Minor, referenced_class_desc AS Class, is_select_all, is_all_columns_found FROM sys.dm_sql_referenced_entities ( 'dbo.uspGetClient', 'OBJECT');
Resultado:
+----------+------------+------------+------------------+-----------------+------------------------+ | Schema | Entity | Minor | Class | is_select_all | is_all_columns_found | |----------+------------+------------+------------------+-----------------+------------------------| | dbo | Client | NULL | OBJECT_OR_COLUMN | 0 | 1 | | dbo | Client | ClientCode | OBJECT_OR_COLUMN | 0 | 1 | | dbo | Client | FirstName | OBJECT_OR_COLUMN | 0 | 1 | | dbo | Client | LastName | OBJECT_OR_COLUMN | 0 | 1 | | NULL | clientcode | NULL | TYPE | 0 | 0 | +----------+------------+------------+------------------+-----------------+------------------------+
Desta vez, o
is_select_all
coluna mostra 0
em todas as linhas. Exemplo 3 – Referenciando uma entidade inexistente
E se sua entidade fizer referência a uma entidade inexistente?
Por exemplo, e se seu colega descartar uma coluna que está realmente sendo referenciada por um procedimento armazenado e você executar
sys.dm_sql_referenced_entities()
contra esse procedimento armazenado? Vamos descobrir.
ALTER TABLE [dbo].[Client] DROP COLUMN LastName;
Acabei de soltar o
LastName
coluna da minha tabela. Agora execute
sys.dm_sql_referenced_entities()
novamente:SELECT referenced_schema_name AS [Schema], referenced_entity_name AS Entity, referenced_minor_name AS Minor, referenced_class_desc AS Class, is_select_all, is_all_columns_found FROM sys.dm_sql_referenced_entities ( 'dbo.uspGetClient', 'OBJECT');
Resultado:
Msg 207, Level 16, State 1, Procedure uspGetClient, Line 4 Invalid column name 'LastName'. Msg 2020, Level 16, State 1, Line 3 The dependencies reported for entity "dbo.uspGetClient" might not include references to all columns. This is either because the entity references an object that does not exist or because of an error in one or more statements in the entity. Before rerunning the query, ensure that there are no errors in the entity and that all objects referenced by the entity exist.
Exemplo 4 – Descarte a tabela inteira
Vamos descobrir o que acontece se derrubarmos a tabela inteira.
DROP TABLE Client;
A mesa foi descartada.
Execute
sys.dm_sql_referenced_entities()
:SELECT referenced_schema_name AS [Schema], referenced_entity_name AS Entity, referenced_minor_name AS Minor, referenced_class_desc AS Class, is_select_all, is_all_columns_found FROM sys.dm_sql_referenced_entities ( 'dbo.uspGetClient', 'OBJECT');
Resultado:
Msg 2020, Level 16, State 1, Line 2 The dependencies reported for entity "dbo.uspGetClient" might not include references to all columns. This is either because the entity references an object that does not exist or because of an error in one or more statements in the entity. Before rerunning the query, ensure that there are no errors in the entity and that all objects referenced by the entity exist.
Exemplo 5 – Retornar todas as colunas
A Microsoft recomenda especificamente não usar o asterisco (
*
) para selecionar todas as colunas de visualizações e funções de gerenciamento dinâmico (das quais sys.dm_sql_referenced_entities()
é um). Isso ocorre porque seus esquemas e os dados que eles retornam podem ser alterados em versões futuras do SQL Server. Isso pode resultar na adição de colunas ao final da lista de colunas em versões futuras, o que pode atrapalhar seu aplicativo se você estiver contando com o asterisco para selecionar todas as colunas. Dito isso, aqui está um exemplo que faz exatamente isso:usa o asterisco (
*
) para selecionar todas as colunas de sys.dm_sql_referenced_entities()
. Estou fazendo isso apenas para mostrar quais colunas são realmente retornadas dessa função (pelo menos no SQL Server 2019). SELECT * FROM sys.dm_sql_referenced_entities ( 'dbo.uspGetClient', 'OBJECT');
Resultado (usando saída vertical):
-[ RECORD 1 ]------------------------- referencing_minor_id | 0 referenced_server_name | NULL referenced_database_name | NULL referenced_schema_name | dbo referenced_entity_name | Client referenced_minor_name | NULL referenced_id | 434100587 referenced_minor_id | 0 referenced_class | 1 referenced_class_desc | OBJECT_OR_COLUMN is_caller_dependent | 0 is_ambiguous | 0 is_selected | 1 is_updated | 0 is_select_all | 0 is_all_columns_found | 1 is_insert_all | 0 is_incomplete | 0 -[ RECORD 2 ]------------------------- referencing_minor_id | 0 referenced_server_name | NULL referenced_database_name | NULL referenced_schema_name | dbo referenced_entity_name | Client referenced_minor_name | ClientCode referenced_id | 434100587 referenced_minor_id | 1 referenced_class | 1 referenced_class_desc | OBJECT_OR_COLUMN is_caller_dependent | 0 is_ambiguous | 0 is_selected | 1 is_updated | 0 is_select_all | 0 is_all_columns_found | 1 is_insert_all | 0 is_incomplete | 0 -[ RECORD 3 ]------------------------- referencing_minor_id | 0 referenced_server_name | NULL referenced_database_name | NULL referenced_schema_name | dbo referenced_entity_name | Client referenced_minor_name | FirstName referenced_id | 434100587 referenced_minor_id | 2 referenced_class | 1 referenced_class_desc | OBJECT_OR_COLUMN is_caller_dependent | 0 is_ambiguous | 0 is_selected | 1 is_updated | 0 is_select_all | 0 is_all_columns_found | 1 is_insert_all | 0 is_incomplete | 0 -[ RECORD 4 ]------------------------- referencing_minor_id | 0 referenced_server_name | NULL referenced_database_name | NULL referenced_schema_name | dbo referenced_entity_name | Client referenced_minor_name | LastName referenced_id | 434100587 referenced_minor_id | 3 referenced_class | 1 referenced_class_desc | OBJECT_OR_COLUMN is_caller_dependent | 0 is_ambiguous | 0 is_selected | 1 is_updated | 0 is_select_all | 0 is_all_columns_found | 1 is_insert_all | 0 is_incomplete | 0 -[ RECORD 5 ]------------------------- referencing_minor_id | 0 referenced_server_name | NULL referenced_database_name | NULL referenced_schema_name | NULL referenced_entity_name | clientcode referenced_minor_name | NULL referenced_id | 257 referenced_minor_id | 0 referenced_class | 6 referenced_class_desc | TYPE is_caller_dependent | 0 is_ambiguous | 0 is_selected | 0 is_updated | 0 is_select_all | 0 is_all_columns_found | 0 is_insert_all | 0 is_incomplete | 0 (5 rows affected)
Documentação oficial
Para obter informações e exemplos mais detalhados, consulte
sys.dm_sql_referenced_entities
no site da Microsoft.