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.