Едно от нещата за sys.dm_sql_referenced_entities()
Функцията за динамично управление на системата е, че можете да я използвате за кръстосани бази данни и междусървърни обекти.
Това означава, че можете да намерите реферирани обекти, които са в различна база данни и дори на различен сървър.
Тази статия предоставя пример за sys.dm_sql_referenced_entities()
връщане на съхранена процедура, която отправя заявки към база данни на свързан сървър.
Пример 1 – Съхранената процедура
Първо, нека създадем съхранена процедура, която връща данни от свързан сървър:
CREATE PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS SELECT AlbumName FROM [Homer].[Music].[dbo].[Albums] WHERE ArtistId = @ArtistId;
Можем да видим, че съхранената процедура използва име от четири части за препратка към таблицата на базата данни. Това е така, защото базата данни е на различен сървър, който е конфигуриран като свързан сървър от сървъра, на който се намира съхранената процедура.
С други думи, тази съхранена процедура връща данни от свързан сървър.
В този пример Homer
е свързаният сървър и Music
е базата данни.
Пример 2 – Изпълнете sys.dm_sql_referenced_entities() срещу съхранената процедура
Сега нека използваме sys.dm_sql_referenced_entities()
за да върнете обектите, посочени в съхранената процедура.
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');
Резултат:
+----------+------------+----------+----------+---------+------------------+ | Server | Database | Schema | Entity | Minor | Class | |----------+------------+----------+----------+---------+------------------| | Homer | Music | dbo | Albums | NULL | OBJECT_OR_COLUMN | +----------+------------+----------+----------+---------+------------------+
Така че той успешно върна таблицата, към която се препраща (въпреки че не колоната/ второстепенното име). Той също така включва името на сървъра ( Homer ) и името на базата данни ( Музика ).
Имайте предвид, че не върнах всички колони в този пример за краткост.
Пример 3 – Изпълнение на sys.dm_sql_referenced_entities() НА свързания сървър
Изглеждат ли тези резултати по-различно от това, което бихме получили, ако съхранената процедура беше на действителния (отдалечен) свързан сървър?
Да пробваме.
Тук преминавам към другия сървър и изпълнявам следния код:
CREATE PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS SELECT AlbumName FROM [dbo].[Albums] WHERE ArtistId = @ArtistId;
Обърнете внимание, че не е необходимо да използвам именуването на четирите части, тъй като се прави заявка за таблици от същия сървър.
Сега стартирайте sys.dm_sql_referenced_entities()
на свързания сървър:
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');
Резултат:
+----------+------------+----------+----------+-----------+------------------+ | 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 | +----------+------------+----------+----------+-----------+------------------+
В този случай колоните се включват в резултатите.
Също така имайте предвид, че колоните сървър и база данни са NULL за всички редове. Това е така, защото нито едно от тях не е включено в дефиницията на съхранената процедура. Ако променя дефиницията на съхранената процедура, за да включва сървъра и базата данни, ще ги видя тук. Сървърът обаче се показва само на първия ред.
ALTER PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS SELECT AlbumName FROM [SQLServer007].[Music].[dbo].[Albums] WHERE ArtistId = @ArtistId;
Резултат:
+--------------+------------+----------+----------+-----------+------------------+ | 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 | +--------------+------------+----------+----------+-----------+------------------+
В този случай името на сървъра е SQLServer007, така че трябваше да го използвам вместо Homer (което е името, което му дадох, когато създавах свързан сървър от другия сървър).
Можем също да използваме OPENQUERY()
ако искаме да се върнем към локалния сървър и да го стартираме срещу свързания сървър:
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'');' );
Резултат:
+--------------+------------+----------+----------+-----------+------------------+ | 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 | +--------------+------------+----------+----------+-----------+------------------+
Имайте предвид, че в този случай трябваше да избягвам всички знаци в единични кавички.
Освен това, ако се опитам да стартирам функцията чрез разпределена заявка (без да използвам OPENQUERY()
), получавам съобщение за грешка 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');
Резултат:
Msg 4122, Level 16, State 1, Line 10 Remote table-valued function calls are not allowed.