Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Пример за sys.dm_sql_referenced_entities() на SQL Server, връщащ обект, който препраща към свързан сървър

Едно от нещата за 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.

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Използване на SQL Server като хранилище за изображения

  2. Примери за преобразуване на „smalldatetime“ в „datetime“ в SQL Server (T-SQL)

  3. R DBI ODBC грешка:nanodbc/nanodbc.cpp:3110:07009:[Microsoft][ODBC драйвер 13 за SQL Server]Невалиден индекс на дескриптор

  4. Най-бързият начин за намиране на остарели функции, които все още се използват в екземпляр на SQL сървър (пример за T-SQL)

  5. Поправка:„BACKUP LOG не може да се извърши, защото няма текущо архивиране на базата данни.“ в SQL Server/SQL Edge