Jedna z věcí o sys.dm_sql_referenced_entities()
Funkce dynamické správy systému spočívá v tom, že ji můžete použít na entitách napříč databázemi a mezi servery.
To znamená, že můžete najít odkazované entity, které jsou v jiné databázi a dokonce i na jiném serveru.
Tento článek poskytuje příklad sys.dm_sql_referenced_entities()
vrácením uložené procedury, která dotazuje databázi na propojeném serveru.
Příklad 1 – Uložená procedura
Nejprve vytvořte uloženou proceduru, která vrátí data z propojeného serveru:
CREATE PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS SELECT AlbumName FROM [Homer].[Music].[dbo].[Albums] WHERE ArtistId = @ArtistId;
Vidíme, že uložená procedura používá k odkazování na databázovou tabulku čtyřdílný název. Důvodem je, že databáze je na jiném serveru, který byl nakonfigurován jako propojený server, než na kterém je uložená procedura umístěna.
Jinými slovy, tato uložená procedura vrací data z propojeného serveru.
V tomto příkladu Homer
je propojený server a Music
je databáze.
Příklad 2 – Spusťte sys.dm_sql_referenced_entities() proti uložené proceduře
Nyní použijeme sys.dm_sql_referenced_entities()
vrátit entity odkazované v uložené proceduře.
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');
Výsledek:
+----------+------------+----------+----------+---------+------------------+ | Server | Database | Schema | Entity | Minor | Class | |----------+------------+----------+----------+---------+------------------| | Homer | Music | dbo | Albums | NULL | OBJECT_OR_COLUMN | +----------+------------+----------+----------+---------+------------------+
Takže úspěšně vrátil odkazovanou tabulku (ačkoli ne sloupec/vedlejší název). Obsahuje také název serveru ( Homer ) a název databáze ( Hudba ).
Všimněte si, že v tomto příkladu jsem kvůli stručnosti nevrátil všechny sloupce.
Příklad 3 – Spuštění sys.dm_sql_referenced_entities() NA propojeném serveru
Liší se tyto výsledky od toho, co bychom získali, kdyby byla uložená procedura na skutečném (vzdáleném) propojeném serveru?
Pojďme to zkusit.
Zde přeskočím na druhý server a spustím následující kód:
CREATE PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS SELECT AlbumName FROM [dbo].[Albums] WHERE ArtistId = @ArtistId;
Všimněte si, že nemusím používat čtyřdílné pojmenování, protože se dotazuje na tabulky na stejném serveru.
Nyní spusťte sys.dm_sql_referenced_entities()
na propojeném serveru:
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');
Výsledek:
+----------+------------+----------+----------+-----------+------------------+ | 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 | +----------+------------+----------+----------+-----------+------------------+
V tomto případě jsou sloupce zahrnuty do výsledků.
Všimněte si také, že sloupce Server a Databáze mají pro všechny řádky hodnotu NULL. Důvodem je, že ani jeden z nich není zahrnut v definici uložené procedury. Pokud změním definici uložené procedury tak, aby zahrnovala server a databázi, viděl bych je zde. Server se však zobrazí pouze v prvním řádku.
ALTER PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS SELECT AlbumName FROM [SQLServer007].[Music].[dbo].[Albums] WHERE ArtistId = @ArtistId;
Výsledek:
+--------------+------------+----------+----------+-----------+------------------+ | 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 | +--------------+------------+----------+----------+-----------+------------------+
V tomto případě je název serveru SQLServer007, takže jsem ho musel použít místo Homer (což je název, který jsem mu dal při vytváření propojeného serveru z druhého serveru).
Můžeme také použít OPENQUERY()
pokud bychom chtěli přejít zpět na místní server a spustit jej proti propojenému serveru:
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'');' );
Výsledek:
+--------------+------------+----------+----------+-----------+------------------+ | 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 | +--------------+------------+----------+----------+-----------+------------------+
Všimněte si, že v tomto případě jsem musel escapovat všechny znaky jednoduchých uvozovek.
Také, pokud se pokusím spustit funkci prostřednictvím distribuovaného dotazu (bez použití OPENQUERY()
), dostávám chybovou zprávu 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');
Výsledek:
Msg 4122, Level 16, State 1, Line 10 Remote table-valued function calls are not allowed.