Uma das coisas sobre o
sys.dm_sql_referenced_entities()
A função de gerenciamento dinâmico do sistema é que você pode usá-lo em entidades entre bancos de dados e servidores cruzados. Isso significa que você pode encontrar entidades referenciadas que estão em um banco de dados diferente e até mesmo em um servidor diferente.
Este artigo fornece um exemplo de
sys.dm_sql_referenced_entities()
retornando um procedimento armazenado que consulta um banco de dados em um servidor vinculado. Exemplo 1 - O Procedimento Armazenado
Primeiro, vamos criar um procedimento armazenado que retorne dados de um servidor vinculado:
CREATE PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS SELECT AlbumName FROM [Homer].[Music].[dbo].[Albums] WHERE ArtistId = @ArtistId;
Podemos ver que o procedimento armazenado usa um nome de quatro partes para fazer referência à tabela do banco de dados. Isso ocorre porque o banco de dados está em um servidor diferente que foi configurado como um servidor vinculado do servidor em que o procedimento armazenado está localizado.
Em outras palavras, esse procedimento armazenado retorna dados de um servidor vinculado.
Neste exemplo,
Homer
é o servidor vinculado e Music
é o banco de dados. Exemplo 2 – Execute sys.dm_sql_referenced_entities() no procedimento armazenado
Agora vamos usar
sys.dm_sql_referenced_entities()
para retornar as entidades referenciadas no procedimento armazenado. SELECT referenced_server_name AS [Server], referenced_database_name AS [Database], referenced_schema_name AS [Schema], referenced_entity_name AS [Entity], referenced_minor_name AS [Minor], referenced_class_desc AS [Class] FROM sys.dm_sql_referenced_entities ( 'dbo.uspGetAlbumsByArtist', 'OBJECT');
Resultado:
+----------+------------+----------+----------+---------+------------------+ | Server | Database | Schema | Entity | Minor | Class | |----------+------------+----------+----------+---------+------------------| | Homer | Music | dbo | Albums | NULL | OBJECT_OR_COLUMN | +----------+------------+----------+----------+---------+------------------+
Portanto, ele retornou com sucesso a tabela que está sendo referenciada (embora não o nome da coluna/menor). Também inclui o nome do servidor ( Homer ) e o nome do banco de dados ( Música ).
Observe que não retornei todas as colunas neste exemplo por questões de brevidade.
Exemplo 3 – Executando sys.dm_sql_referenced_entities() NO Servidor Vinculado
Esses resultados parecem diferentes do que obteríamos se o procedimento armazenado estivesse no servidor vinculado real (remoto)?
Vamos tentar.
Aqui, eu pulo para o outro servidor e executo o seguinte código:
CREATE PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS SELECT AlbumName FROM [dbo].[Albums] WHERE ArtistId = @ArtistId;
Observe que não preciso usar a nomenclatura de quatro partes, visto que está consultando tabelas no mesmo servidor.
Agora execute
sys.dm_sql_referenced_entities()
no servidor vinculado:SELECT referenced_server_name AS [Server], referenced_database_name AS [Database], referenced_schema_name AS [Schema], referenced_entity_name AS [Entity], referenced_minor_name AS [Minor], referenced_class_desc AS [Class] FROM sys.dm_sql_referenced_entities ( '[dbo].uspGetAlbumsByArtist', 'OBJECT');
Resultado:
+----------+------------+----------+----------+-----------+------------------+ | Server | Database | Schema | Entity | Minor | Class | |----------+------------+----------+----------+-----------+------------------| | NULL | NULL | dbo | Albums | NULL | OBJECT_OR_COLUMN | | NULL | NULL | dbo | Albums | AlbumName | OBJECT_OR_COLUMN | | NULL | NULL | dbo | Albums | ArtistId | OBJECT_OR_COLUMN | +----------+------------+----------+----------+-----------+------------------+
Nesse caso, as colunas são incluídas nos resultados.
Observe também que as colunas Servidor e Banco de Dados são NULL para todas as linhas. Isso ocorre porque nenhum deles está incluído na definição do procedimento armazenado. Se eu alterar a definição do procedimento armazenado para incluir o servidor e o banco de dados, eu os veria aqui. No entanto, o servidor aparece apenas na primeira linha.
ALTER PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS SELECT AlbumName FROM [SQLServer007].[Music].[dbo].[Albums] WHERE ArtistId = @ArtistId;
Resultado:
+--------------+------------+----------+----------+-----------+------------------+ | Server | Database | Schema | Entity | Minor | Class | |--------------+------------+----------+----------+-----------+------------------| | SQLServer007 | Music | dbo | Albums | NULL | OBJECT_OR_COLUMN | | NULL | Music | dbo | Albums | AlbumName | OBJECT_OR_COLUMN | | NULL | Music | dbo | Albums | ArtistId | OBJECT_OR_COLUMN | +--------------+------------+----------+----------+-----------+------------------+
Nesse caso, o nome do servidor é SQLServer007, então tive que usar isso em vez de Homer (que é o nome que dei ao criar um servidor vinculado do outro servidor).
Também podemos usar
OPENQUERY()
se quisermos voltar para o servidor local e executá-lo no servidor vinculado:SELECT * FROM OPENQUERY( Homer, 'SELECT referenced_server_name AS [Server], referenced_database_name AS [Database], referenced_schema_name AS [Schema], referenced_entity_name AS [Entity], referenced_minor_name AS [Minor], referenced_class_desc AS [Class] FROM sys.dm_sql_referenced_entities ( ''[dbo].uspGetAlbumsByArtist'', ''OBJECT'');' );
Resultado:
+--------------+------------+----------+----------+-----------+------------------+ | Server | Database | Schema | Entity | Minor | Class | |--------------+------------+----------+----------+-----------+------------------| | SQLServer007 | Music | dbo | Albums | NULL | OBJECT_OR_COLUMN | | NULL | Music | dbo | Albums | AlbumName | OBJECT_OR_COLUMN | | NULL | Music | dbo | Albums | ArtistId | OBJECT_OR_COLUMN | +--------------+------------+----------+----------+-----------+------------------+
Observe que neste caso eu tive que escapar de todos os caracteres de aspas simples.
Além disso, se eu tentar executar a função por meio de uma consulta distribuída (sem usar
OPENQUERY()
), recebo a mensagem de erro 4122:SELECT referenced_server_name AS [Server], referenced_database_name AS [Database], referenced_schema_name AS [Schema], referenced_entity_name AS [Entity], referenced_minor_name AS [Minor], referenced_class_desc AS [Class] FROM [Homer].[Music].[sys].dm_sql_referenced_entities ( '[dbo].[uspGetAlbumsByArtist]', 'OBJECT');
Resultado:
Msg 4122, Level 16, State 1, Line 10 Remote table-valued function calls are not allowed.