En af tingene ved sys.dm_sql_referenced_entities()
System Dynamic Management funktion er, at du kan bruge den på tværs af databaser og på tværs af serverenheder.
Det betyder, at du kan finde refererede enheder, der er i en anden database og endda på en anden server.
Denne artikel giver et eksempel på sys.dm_sql_referenced_entities()
returnering af en lagret procedure, der forespørger en database på en forbundet server.
Eksempel 1 – Den lagrede procedure
Lad os først oprette en lagret procedure, der returnerer data fra en forbundet server:
CREATE PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS SELECT AlbumName FROM [Homer].[Music].[dbo].[Albums] WHERE ArtistId = @ArtistId;
Vi kan se, at den lagrede procedure bruger et firedelt navn til at referere til databasetabellen. Dette skyldes, at databasen er på en anden server, som er konfigureret som en sammenkædet server fra den server, som den lagrede procedure er placeret på.
Med andre ord returnerer denne lagrede procedure data fra en forbundet server.
I dette eksempel, Homer
er den linkede server og Music
er databasen.
Eksempel 2 – Kør sys.dm_sql_referenced_entities() mod den lagrede procedure
Lad os nu bruge sys.dm_sql_referenced_entities()
for at returnere de enheder, der henvises til i den lagrede 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');
Resultat:
+----------+------------+----------+----------+---------+------------------+ | Server | Database | Schema | Entity | Minor | Class | |----------+------------+----------+----------+---------+------------------| | Homer | Music | dbo | Albums | NULL | OBJECT_OR_COLUMN | +----------+------------+----------+----------+---------+------------------+
Så det returnerede med succes den tabel, der refereres til (selvom ikke kolonnen/underordnet navn). Det inkluderer også servernavnet ( Homer ) og databasenavnet ( Musik ).
Bemærk, at jeg for korthedens skyld ikke returnerede alle kolonner i dette eksempel.
Eksempel 3 – Kørsel af sys.dm_sql_referenced_entities() PÅ den sammenkædede server
Ser disse resultater anderledes ud end, hvad vi ville få, hvis den lagrede procedure var på den faktiske (fjern-)linkede server?
Lad os prøve det.
Her hopper jeg over til den anden server og kører følgende kode:
CREATE PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS SELECT AlbumName FROM [dbo].[Albums] WHERE ArtistId = @ArtistId;
Bemærk, at jeg ikke behøver at bruge de fire dele navngivning, da det forespørger tabeller på den samme server.
Kør nu sys.dm_sql_referenced_entities()
på den linkede 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');
Resultat:
+----------+------------+----------+----------+-----------+------------------+ | 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 | +----------+------------+----------+----------+-----------+------------------+
I dette tilfælde er kolonnerne inkluderet i resultaterne.
Bemærk også, at kolonnerne Server og Database er NULL for alle rækker. Dette skyldes, at ingen af disse er inkluderet i den lagrede procedures definition. Hvis jeg ændrer den lagrede procedures definition til at inkludere serveren og databasen, vil jeg se dem her. Serveren vises dog kun i første række.
ALTER PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS SELECT AlbumName FROM [SQLServer007].[Music].[dbo].[Albums] WHERE ArtistId = @ArtistId;
Resultat:
+--------------+------------+----------+----------+-----------+------------------+ | 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 | +--------------+------------+----------+----------+-----------+------------------+
I dette tilfælde er serverens navn SQLServer007, så jeg var nødt til at bruge det i stedet for Homer (som er det navn, jeg gav den, da jeg oprettede en linket server fra den anden server).
Vi kan også bruge OPENQUERY()
hvis vi ønskede at hoppe tilbage til den lokale server og køre den mod den linkede 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'');' );
Resultat:
+--------------+------------+----------+----------+-----------+------------------+ | 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 | +--------------+------------+----------+----------+-----------+------------------+
Bemærk, at i dette tilfælde var jeg nødt til at undslippe alle de enkelte anførselstegn.
Også, hvis jeg prøver at køre funktionen via en distribueret forespørgsel (uden at bruge OPENQUERY()
), får jeg fejlmeddelelse 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');
Resultat:
Msg 4122, Level 16, State 1, Line 10 Remote table-valued function calls are not allowed.