sql >> Databáze >  >> RDS >> Sqlserver

Příklad sys.dm_sql_referenced_entities() SQL Serveru vracejícího entitu, která odkazuje na propojený server

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.

  1. Oracle PL/SQL – Zvyšte uživatelsky definovanou výjimku pomocí vlastního SQLERRM

  2. Vytvořte tabulku dvou typů v PostgreSQL

  3. Jak nasadit produkční cluster MySQL nebo MariaDB Galera pomocí ClusterControl

  4. Jak ignorovat chyby pomocí psql \copy meta-command