Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Przykład sys.dm_sql_referenced_entities() SQL Servera zwracającego jednostkę, która odwołuje się do połączonego serwera

Jedna z rzeczy związanych z sys.dm_sql_referenced_entities() funkcja dynamicznego zarządzania systemem polega na tym, że można go używać w jednostkach międzybazowych i międzyserwerowych.

Oznacza to, że możesz znaleźć jednostki odniesienia, które znajdują się w innej bazie danych, a nawet na innym serwerze.

Ten artykuł zawiera przykład sys.dm_sql_referenced_entities() zwracając procedurę składowaną, która wysyła zapytania do bazy danych na serwerze połączonym.

Przykład 1 – Procedura składowana

Najpierw utwórzmy procedurę składowaną, która zwraca dane z połączonego serwera:

CREATE PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS
SELECT AlbumName
FROM [Homer].[Music].[dbo].[Albums]
WHERE ArtistId = @ArtistId;

Widzimy, że procedura składowana używa czteroczęściowej nazwy do odwoływania się do tabeli bazy danych. Dzieje się tak, ponieważ baza danych znajduje się na innym serwerze, który został skonfigurowany jako serwer połączony z serwerem, na którym znajduje się procedura składowana.

Innymi słowy, ta procedura składowana zwraca dane z połączonego serwera.

W tym przykładzie Homer jest połączonym serwerem, a Music to baza danych.

Przykład 2 – Uruchom sys.dm_sql_referenced_entities() przeciwko procedurze przechowywanej

Teraz użyjmy sys.dm_sql_referenced_entities() aby zwrócić jednostki, do których odwołuje się procedura składowana.

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');

Wynik:

+----------+------------+----------+----------+---------+------------------+
| Server   | Database   | Schema   | Entity   | Minor   | Class            |
|----------+------------+----------+----------+---------+------------------|
| Homer    | Music      | dbo      | Albums   | NULL    | OBJECT_OR_COLUMN |
+----------+------------+----------+----------+---------+------------------+

Więc pomyślnie zwrócił tabelę, do której się odwołujemy (choć nie nazwę kolumny/pobocznej). Zawiera również nazwę serwera ( Homer ) i nazwę bazy danych ( Muzyka ).

Zwróć uwagę, że nie zwróciłem wszystkich kolumn w tym przykładzie ze względu na zwięzłość.

Przykład 3 – Uruchamianie sys.dm_sql_referenced_entities() NA połączonym serwerze

Czy te wyniki wyglądają inaczej niż te, które otrzymalibyśmy, gdyby procedura składowana znajdowała się na rzeczywistym (zdalnym) serwerze połączonym?

Spróbujmy.

Tutaj przeskakuję na inny serwer i uruchamiam następujący kod:

CREATE PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS
SELECT AlbumName
FROM [dbo].[Albums]
WHERE ArtistId = @ArtistId;

Zauważ, że nie muszę używać czteroczęściowego nazewnictwa, ponieważ odpytuje on tabele na tym samym serwerze.

Teraz uruchom sys.dm_sql_referenced_entities() na połączonym serwerze:

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');

Wynik:

+----------+------------+----------+----------+-----------+------------------+
| 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 |
+----------+------------+----------+----------+-----------+------------------+

W takim przypadku kolumny są uwzględniane w wynikach.

Należy również zauważyć, że kolumny Serwer i Baza danych mają wartość NULL we wszystkich wierszach. Dzieje się tak, ponieważ żaden z nich nie jest zawarty w definicji procedury składowanej. Jeśli zmienię definicję procedury składowanej tak, aby zawierała serwer i bazę danych, zobaczyłbym je tutaj. Jednak serwer pojawia się tylko w pierwszym wierszu.

ALTER PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS
SELECT AlbumName
FROM [SQLServer007].[Music].[dbo].[Albums]
WHERE ArtistId = @ArtistId;

Wynik:

+--------------+------------+----------+----------+-----------+------------------+
| 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 |
+--------------+------------+----------+----------+-----------+------------------+

W tym przypadku nazwa serwera to SQLServer007, więc musiałem użyć tej nazwy zamiast Homera (takiej nazwy nadałem mu podczas tworzenia serwera połączonego z innego serwera).

Możemy również użyć OPENQUERY() gdybyśmy chcieli wrócić do lokalnego serwera i uruchomić go na połączonym serwerze:

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'');'
);

Wynik:

+--------------+------------+----------+----------+-----------+------------------+
| 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 |
+--------------+------------+----------+----------+-----------+------------------+

Zauważ, że w tym przypadku musiałem uciec przed wszystkimi znakami pojedynczego cudzysłowu.

Ponadto, jeśli spróbuję uruchomić funkcję za pomocą zapytania rozproszonego (bez użycia OPENQUERY() ), otrzymuję komunikat o błędzie 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');

Wynik:

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. Dlaczego 1899-12-30 jest datą zerową w programie Access/SQL Server zamiast 12/31?

  2. Nieprawidłowa nazwa kolumny błąd sql

  3. Uszkodzony plik eksportu SQL Server BCP?

  4. Użyj COLUMNPROPERTY(), aby zwrócić informacje o kolumnie lub parametrze w SQL Server

  5. Czy można używać wyszukiwania pełnotekstowego (FTS) z LINQ?