One of the things about the sys.dm_sql_referenced_entities()
system dynamic management function is that you can use it on cross-database and cross-server entities.
This means you can find referenced entities that are in a different database and even on a different server.
This article provides an example of sys.dm_sql_referenced_entities()
returning a stored procedure that queries a database on a linked server.
Example 1 – The Stored Procedure
First, let’s create a stored procedure that returns data from a linked server:
CREATE PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS SELECT AlbumName FROM [Homer].[Music].[dbo].[Albums] WHERE ArtistId = @ArtistId;
We can see that the stored procedure uses a four-part name to reference the database table. This is because the database is on a different server which has been configured as a linked server from the server that the stored procedure is located.
In other words, this stored procedure returns data from a linked server.
In this example, Homer
is the linked server, and Music
is the database.
Example 2 – Run sys.dm_sql_referenced_entities() Against the Stored Procedure
Now let’s use sys.dm_sql_referenced_entities()
to return the entities referenced in the stored procedure.
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');
Result:
+----------+------------+----------+----------+---------+------------------+ | Server | Database | Schema | Entity | Minor | Class | |----------+------------+----------+----------+---------+------------------| | Homer | Music | dbo | Albums | NULL | OBJECT_OR_COLUMN | +----------+------------+----------+----------+---------+------------------+
So it successfully returned the table being referenced (although not the column/minor name). It also includes the server name (Homer) and the database name (Music).
Note that I didn’t return all columns in this example for the sake of brevity.
Example 3 – Running sys.dm_sql_referenced_entities() ON the Linked Server
Do those results look any different to what we’d get if the stored procedure was on the actual (remote) linked server?
Let’s try it.
Here, I jump over to the other server and run the following code:
CREATE PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS SELECT AlbumName FROM [dbo].[Albums] WHERE ArtistId = @ArtistId;
Note that I don’t need to use the four part naming, seeing as it’s querying tables the same server.
Now run sys.dm_sql_referenced_entities()
on the linked server:
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');
Result:
+----------+------------+----------+----------+-----------+------------------+ | 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 | +----------+------------+----------+----------+-----------+------------------+
In this case, the columns are included in the results.
Also note that the Server and Database columns are NULL for all rows. This is because neither of those are included in the stored procedure’s definition. If I alter the stored procedure’s definition to include the server and the database, I would see them here. However, the server only appears in the first row.
ALTER PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS SELECT AlbumName FROM [SQLServer007].[Music].[dbo].[Albums] WHERE ArtistId = @ArtistId;
Result:
+--------------+------------+----------+----------+-----------+------------------+ | 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 | +--------------+------------+----------+----------+-----------+------------------+
In this case, the server’s name is SQLServer007, so I had to use that instead of Homer (which is the name I gave it when creating a linked server from the other server).
We can also use OPENQUERY()
if we wanted to jump back to the local server and run it against the linked server:
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'');' );
Result:
+--------------+------------+----------+----------+-----------+------------------+ | 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 | +--------------+------------+----------+----------+-----------+------------------+
Note that in this case I had to escape all the single quote characters.
Also, if I try to run the function via a distributed query (without using OPENQUERY()
), I get error msg 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');
Result:
Msg 4122, Level 16, State 1, Line 10 Remote table-valued function calls are not allowed.