sql >> Databasteknik >  >> RDS >> Sqlserver

Exempel på SQL Servers sys.dm_sql_referenced_entities() som returnerar en enhet som refererar till en länkad server

En av sakerna med sys.dm_sql_referenced_entities() systemets dynamiska hanteringsfunktion är att du kan använda den på korsdatabas- och serverenheter.

Det betyder att du kan hitta refererade enheter som finns i en annan databas och till och med på en annan server.

Den här artikeln ger ett exempel på sys.dm_sql_referenced_entities() returnera en lagrad procedur som frågar efter en databas på en länkad server.

Exempel 1 – Den lagrade proceduren

Låt oss först skapa en lagrad procedur som returnerar data från en länkad server:

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

Vi kan se att den lagrade proceduren använder ett fyrdelat namn för att referera till databastabellen. Detta beror på att databasen finns på en annan server som har konfigurerats som en länkad server från den server som den lagrade proceduren finns.

Med andra ord, denna lagrade procedur returnerar data från en länkad server.

I det här exemplet, Homer är den länkade servern och Music är databasen.

Exempel 2 – Kör sys.dm_sql_referenced_entities() mot den lagrade proceduren

Låt oss nu använda sys.dm_sql_referenced_entities() för att returnera de enheter som refereras till i den lagrade proceduren.

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

Resultat:

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

Så den returnerade framgångsrikt tabellen som refereras till (även om inte kolumnen/birollnamnet). Det inkluderar även servernamnet ( Homer ) och databasnamnet ( Musik ).

Observera att jag inte returnerade alla kolumner i det här exemplet för korthetens skull.

Exempel 3 – Kör sys.dm_sql_referenced_entities() PÅ den länkade servern

Ser dessa resultat annorlunda ut än vad vi skulle få om den lagrade proceduren var på den faktiska (fjärrlänkade) servern?

Låt oss testa det.

Här hoppar jag över till den andra servern och kör följande kod:

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

Observera att jag inte behöver använda namngivningen med fyra delar, eftersom det frågar efter tabeller på samma server.

Kör nu sys.dm_sql_referenced_entities() på den länkade servern:

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

Resultat:

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

I det här fallet ingår kolumnerna i resultaten.

Observera också att server- och databaskolumnerna är NULL för alla rader. Detta beror på att ingen av dessa ingår i den lagrade procedurens definition. Om jag ändrar den lagrade procedurens definition för att inkludera servern och databasen, skulle jag se dem här. Servern visas dock bara på första raden.

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

Resultat:

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

I det här fallet är serverns namn SQLServer007, så jag var tvungen att använda det istället för Homer (vilket är namnet jag gav den när jag skapade en länkad server från den andra servern).

Vi kan också använda OPENQUERY() om vi ville hoppa tillbaka till den lokala servern och köra den mot den länkade servern:

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

Resultat:

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

Observera att i det här fallet var jag tvungen att undvika alla enstaka citattecken.

Dessutom, om jag försöker köra funktionen via en distribuerad fråga (utan att använda OPENQUERY() ), får jag felmeddelande 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');

Resultat:

Msg 4122, Level 16, State 1, Line 10
Remote table-valued function calls are not allowed.

  1. Hur ökar man maxanslutningarna i postgres?

  2. Hur man hittar aktuella öppna markörer i Oracle

  3. sp_executesql är långsam med parametrar

  4. Oracle Dynamic Pivoting