Een van de dingen over de sys.dm_sql_referenced_entities()
systeem dynamisch beheer functie is dat u het kunt gebruiken op cross-database en cross-server entiteiten.
Dit betekent dat u entiteiten waarnaar wordt verwezen kunt vinden die zich in een andere database en zelfs op een andere server bevinden.
Dit artikel geeft een voorbeeld van sys.dm_sql_referenced_entities()
het retourneren van een opgeslagen procedure die een database op een gekoppelde server opvraagt.
Voorbeeld 1 – De opgeslagen procedure
Laten we eerst een opgeslagen procedure maken die gegevens retourneert van een gekoppelde server:
CREATE PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS SELECT AlbumName FROM [Homer].[Music].[dbo].[Albums] WHERE ArtistId = @ArtistId;
We kunnen zien dat de opgeslagen procedure een vierdelige naam gebruikt om naar de databasetabel te verwijzen. Dit komt omdat de database zich op een andere server bevindt die is geconfigureerd als een gekoppelde server dan de server waarop de opgeslagen procedure zich bevindt.
Met andere woorden, deze opgeslagen procedure retourneert gegevens van een gekoppelde server.
In dit voorbeeld, Homer
is de gekoppelde server, en Music
is de database.
Voorbeeld 2 – Voer sys.dm_sql_referenced_entities() uit tegen de opgeslagen procedure
Laten we nu sys.dm_sql_referenced_entities()
gebruiken om de entiteiten waarnaar wordt verwezen in de opgeslagen procedure te retourneren.
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');
Resultaat:
+----------+------------+----------+----------+---------+------------------+ | Server | Database | Schema | Entity | Minor | Class | |----------+------------+----------+----------+---------+------------------| | Homer | Music | dbo | Albums | NULL | OBJECT_OR_COLUMN | +----------+------------+----------+----------+---------+------------------+
Dus het heeft met succes de tabel geretourneerd waarnaar wordt verwezen (hoewel niet de kolom / secundaire naam). Het bevat ook de servernaam ( Homer ) en de databasenaam ( Muziek ).
Merk op dat ik omwille van de beknoptheid niet alle kolommen in dit voorbeeld heb geretourneerd.
Voorbeeld 3 – sys.dm_sql_referenced_entities() uitvoeren op de gekoppelde server
Zien die resultaten er anders uit dan wat we zouden krijgen als de opgeslagen procedure op de daadwerkelijke (externe) gekoppelde server was?
Laten we het proberen.
Hier spring ik naar de andere server en voer de volgende code uit:
CREATE PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS SELECT AlbumName FROM [dbo].[Albums] WHERE ArtistId = @ArtistId;
Merk op dat ik de vierdelige naamgeving niet hoef te gebruiken, aangezien het dezelfde server doorzoekt.
Voer nu sys.dm_sql_referenced_entities()
uit op de gekoppelde 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');
Resultaat:
+----------+------------+----------+----------+-----------+------------------+ | 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 dit geval worden de kolommen opgenomen in de resultaten.
Houd er ook rekening mee dat de kolommen Server en Database voor alle rijen NULL zijn. Dit komt omdat geen van beide is opgenomen in de definitie van de opgeslagen procedure. Als ik de definitie van de opgeslagen procedure zou wijzigen om de server en de database op te nemen, zou ik ze hier zien. De server verschijnt echter alleen op de eerste rij.
ALTER PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS SELECT AlbumName FROM [SQLServer007].[Music].[dbo].[Albums] WHERE ArtistId = @ArtistId;
Resultaat:
+--------------+------------+----------+----------+-----------+------------------+ | 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 dit geval is de naam van de server SQLServer007, dus ik moest die gebruiken in plaats van Homer (de naam die ik hem gaf bij het maken van een gekoppelde server vanaf de andere server).
We kunnen ook OPENQUERY()
. gebruiken als we terug willen springen naar de lokale server en het willen uitvoeren op de gekoppelde 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'');' );
Resultaat:
+--------------+------------+----------+----------+-----------+------------------+ | 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 | +--------------+------------+----------+----------+-----------+------------------+
Merk op dat ik in dit geval alle enkele aanhalingstekens moest escapen.
Ook als ik de functie probeer uit te voeren via een gedistribueerde query (zonder OPENQUERY()
te gebruiken ), krijg ik foutmelding 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');
Resultaat:
Msg 4122, Level 16, State 1, Line 10 Remote table-valued function calls are not allowed.