Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Trova entità di riferimento in SQL Server:sys.dm_sql_referenced_entities

In SQL Server puoi utilizzare sys.dm_sql_referenced_entities() funzione di gestione dinamica del sistema per ottenere un elenco di tutte le entità definite dall'utente a cui si fa riferimento per nome, nella definizione di una determinata entità.

In altre parole, restituisce un elenco di tutte le entità definite dall'utente da cui dipende un'entità specifica.

In particolare, segnala i seguenti tipi di entità a cui fa riferimento l'entità di riferimento specificata:

  • Entità legate allo schema
  • Entità non legate allo schema
  • Entità cross-database e cross-server
  • Dipendenze a livello di colonna da entità associate a schemi e non associate a schemi
  • Tipi definiti dall'utente (alias e CLR UDT)
  • Raccolte di schemi XML
  • Funzioni di partizione

Sintassi

La sintassi è questa:

sys.dm_sql_referenced_entities (  
    ' [ schema_name. ] referencing_entity_name ' ,
    '  ' )  
  
 ::=  
{  
    OBJECT  
  | DATABASE_DDL_TRIGGER  
  | SERVER_DDL_TRIGGER  
}

Esempio 1 – Esempio di base

Ecco un esempio di utilizzo:

USE Test;
SELECT 
  referenced_schema_name AS [Schema],
  referenced_entity_name AS Entity,
  referenced_minor_name AS Minor,
  referenced_class_desc AS Class,
  is_select_all,
  is_all_columns_found
FROM sys.dm_sql_referenced_entities (
    'dbo.uspGetClient', 
    'OBJECT');

Risultato:

+----------+------------+------------+------------------+-----------------+------------------------+
| Schema   | Entity     | Minor      | Class            | is_select_all   | is_all_columns_found   |
|----------+------------+------------+------------------+-----------------+------------------------|
| dbo      | Client     | NULL       | OBJECT_OR_COLUMN | 1               | 1                      |
| dbo      | Client     | ClientCode | OBJECT_OR_COLUMN | 1               | 1                      |
| dbo      | Client     | FirstName  | OBJECT_OR_COLUMN | 1               | 1                      |
| dbo      | Client     | LastName   | OBJECT_OR_COLUMN | 1               | 1                      |
| NULL     | clientcode | NULL       | TYPE             | 0               | 0                      |
+----------+------------+------------+------------------+-----------------+------------------------+

Qui ottengo tutte le entità a cui si fa riferimento nel dbo.uspGetClient procedura memorizzata. In questo caso ci sono cinque entità.

Il primo è il tavolo chiamato “Cliente”. Le tre successive sono tutte colonne all'interno di quella tabella. L'ultimo è un tipo di dati alias definito dall'utente chiamato "codice cliente".

Possiamo anche vedere che i primi quattro sono usati in un'istruzione select che usa l'asterisco (* ) carattere jolly per selezionare tutte le colonne (perché il loro is_select_all è impostato su 1 ).

Ecco la definizione effettiva utilizzata per creare la stored procedure che stiamo analizzando:

CREATE PROCEDURE [dbo].[uspGetClient] @ClientCode clientcode AS
SELECT * 
FROM [dbo].[Client]
WHERE ClientCode = @ClientCode;

Sì, è una procedura memorizzata molto semplice, ma è l'ideale per i nostri scopi. Possiamo vedere tutte le entità referenziate come restituite da sys.dm_sql_referenced_entities() .

Possiamo anche vedere che la procedura consiste in un singolo SELECT query che utilizza il carattere jolly asterisco per selezionare tutte le colonne.

Esempio 2:rimuovere "Seleziona tutto" (* )

Modifichiamo la stored procedure in modo che non utilizzi il carattere jolly asterisco per selezionare tutte le colonne.

ALTER PROCEDURE [dbo].[uspGetClient] @ClientCode clientcode AS
SELECT 
    FirstName,
    LastName
FROM [dbo].[Client]
WHERE ClientCode = @ClientCode;

Quindi ora restituisce esplicitamente le colonne "Nome" e "Cognome". Nessun carattere jolly trovato.

Ora esegui sys.dm_sql_referenced_entities() ancora:

USE Test;
SELECT 
  referenced_schema_name AS [Schema],
  referenced_entity_name AS Entity,
  referenced_minor_name AS Minor,
  referenced_class_desc AS Class,
  is_select_all,
  is_all_columns_found
FROM sys.dm_sql_referenced_entities (
    'dbo.uspGetClient', 
    'OBJECT');

Risultato:

+----------+------------+------------+------------------+-----------------+------------------------+
| Schema   | Entity     | Minor      | Class            | is_select_all   | is_all_columns_found   |
|----------+------------+------------+------------------+-----------------+------------------------|
| dbo      | Client     | NULL       | OBJECT_OR_COLUMN | 0               | 1                      |
| dbo      | Client     | ClientCode | OBJECT_OR_COLUMN | 0               | 1                      |
| dbo      | Client     | FirstName  | OBJECT_OR_COLUMN | 0               | 1                      |
| dbo      | Client     | LastName   | OBJECT_OR_COLUMN | 0               | 1                      |
| NULL     | clientcode | NULL       | TYPE             | 0               | 0                      |
+----------+------------+------------+------------------+-----------------+------------------------+

Questa volta, il is_select_all la colonna mostra 0 su tutte le righe.

Esempio 3 – Riferimento a un'entità inesistente

Cosa succede se la tua entità fa riferimento a un'entità inesistente?

Ad esempio, cosa succede se il tuo collega elimina una colonna a cui fa effettivamente riferimento una stored procedure e quindi esegui sys.dm_sql_referenced_entities() contro quella procedura memorizzata?

Scopriamolo.

ALTER TABLE [dbo].[Client] 
DROP COLUMN LastName;

Ho appena lasciato il LastName colonna dalla mia tabella.

Ora esegui sys.dm_sql_referenced_entities() ancora:

SELECT 
  referenced_schema_name AS [Schema],
  referenced_entity_name AS Entity,
  referenced_minor_name AS Minor,
  referenced_class_desc AS Class,
  is_select_all,
  is_all_columns_found
FROM sys.dm_sql_referenced_entities (
    'dbo.uspGetClient', 
    'OBJECT');

Risultato:

Msg 207, Level 16, State 1, Procedure uspGetClient, Line 4
Invalid column name 'LastName'.
Msg 2020, Level 16, State 1, Line 3
The dependencies reported for entity "dbo.uspGetClient" might not include references to all columns. This is either because the entity references an object that does not exist or because of an error in one or more statements in the entity. Before rerunning the query, ensure that there are no errors in the entity and that all objects referenced by the entity exist.

Esempio 4:elimina l'intera tabella

Scopriamo cosa succede se abbandoniamo l'intero tavolo.

DROP TABLE Client;

La tabella è stata eliminata.

Esegui sys.dm_sql_referenced_entities() :

SELECT 
  referenced_schema_name AS [Schema],
  referenced_entity_name AS Entity,
  referenced_minor_name AS Minor,
  referenced_class_desc AS Class,
  is_select_all,
  is_all_columns_found
FROM sys.dm_sql_referenced_entities (
    'dbo.uspGetClient', 
    'OBJECT');

Risultato:

Msg 2020, Level 16, State 1, Line 2
The dependencies reported for entity "dbo.uspGetClient" might not include references to all columns. This is either because the entity references an object that does not exist or because of an error in one or more statements in the entity. Before rerunning the query, ensure that there are no errors in the entity and that all objects referenced by the entity exist.

Esempio 5 – Restituisci tutte le colonne

Microsoft sconsiglia espressamente di utilizzare l'asterisco (* ) per selezionare tutte le colonne dalle viste e funzioni a gestione dinamica (di cui sys.dm_sql_referenced_entities() è uno). Ciò è dovuto al fatto che i relativi schemi e i dati restituiti potrebbero cambiare nelle versioni future di SQL Server. Ciò potrebbe comportare l'aggiunta di colonne alla fine dell'elenco delle colonne nelle versioni future, il che potrebbe rovinare la tua applicazione se fai affidamento sull'asterisco per selezionare tutte le colonne.

Detto questo, ecco un esempio che fa proprio questo:usa l'asterisco (* ) per selezionare tutte le colonne da sys.dm_sql_referenced_entities() . Lo sto facendo solo per mostrarti quali colonne vengono effettivamente restituite da questa funzione (almeno in SQL Server 2019).

SELECT *
FROM sys.dm_sql_referenced_entities (
    'dbo.uspGetClient', 
    'OBJECT');

Risultato (usando l'output verticale):

-[ RECORD 1 ]-------------------------
referencing_minor_id     | 0
referenced_server_name   | NULL
referenced_database_name | NULL
referenced_schema_name   | dbo
referenced_entity_name   | Client
referenced_minor_name    | NULL
referenced_id            | 434100587
referenced_minor_id      | 0
referenced_class         | 1
referenced_class_desc    | OBJECT_OR_COLUMN
is_caller_dependent      | 0
is_ambiguous             | 0
is_selected              | 1
is_updated               | 0
is_select_all            | 0
is_all_columns_found     | 1
is_insert_all            | 0
is_incomplete            | 0
-[ RECORD 2 ]-------------------------
referencing_minor_id     | 0
referenced_server_name   | NULL
referenced_database_name | NULL
referenced_schema_name   | dbo
referenced_entity_name   | Client
referenced_minor_name    | ClientCode
referenced_id            | 434100587
referenced_minor_id      | 1
referenced_class         | 1
referenced_class_desc    | OBJECT_OR_COLUMN
is_caller_dependent      | 0
is_ambiguous             | 0
is_selected              | 1
is_updated               | 0
is_select_all            | 0
is_all_columns_found     | 1
is_insert_all            | 0
is_incomplete            | 0
-[ RECORD 3 ]-------------------------
referencing_minor_id     | 0
referenced_server_name   | NULL
referenced_database_name | NULL
referenced_schema_name   | dbo
referenced_entity_name   | Client
referenced_minor_name    | FirstName
referenced_id            | 434100587
referenced_minor_id      | 2
referenced_class         | 1
referenced_class_desc    | OBJECT_OR_COLUMN
is_caller_dependent      | 0
is_ambiguous             | 0
is_selected              | 1
is_updated               | 0
is_select_all            | 0
is_all_columns_found     | 1
is_insert_all            | 0
is_incomplete            | 0
-[ RECORD 4 ]-------------------------
referencing_minor_id     | 0
referenced_server_name   | NULL
referenced_database_name | NULL
referenced_schema_name   | dbo
referenced_entity_name   | Client
referenced_minor_name    | LastName
referenced_id            | 434100587
referenced_minor_id      | 3
referenced_class         | 1
referenced_class_desc    | OBJECT_OR_COLUMN
is_caller_dependent      | 0
is_ambiguous             | 0
is_selected              | 1
is_updated               | 0
is_select_all            | 0
is_all_columns_found     | 1
is_insert_all            | 0
is_incomplete            | 0
-[ RECORD 5 ]-------------------------
referencing_minor_id     | 0
referenced_server_name   | NULL
referenced_database_name | NULL
referenced_schema_name   | NULL
referenced_entity_name   | clientcode
referenced_minor_name    | NULL
referenced_id            | 257
referenced_minor_id      | 0
referenced_class         | 6
referenced_class_desc    | TYPE
is_caller_dependent      | 0
is_ambiguous             | 0
is_selected              | 0
is_updated               | 0
is_select_all            | 0
is_all_columns_found     | 0
is_insert_all            | 0
is_incomplete            | 0
(5 rows affected)

Documentazione ufficiale

Per informazioni ed esempi più dettagliati, vedere sys.dm_sql_referenced_entities sul sito Web Microsoft.