V SQL Server můžete použít sys.dm_sql_referenced_entities()
funkce systémové dynamické správy k získání seznamu všech uživatelsky definovaných entit, na které se odkazuje jménem v definici dané entity.
Jinými slovy, vrací seznam všech uživatelsky definovaných entit, na kterých závisí konkrétní entita.
Konkrétně uvádí následující typy entit, na které odkazuje zadaná odkazující entita:
- Entity vázané na schéma
- Entity bez vazby na schéma
- entity napříč databázemi a servery
- Závislosti na úrovni sloupců na entitách vázaných na schéma a nevázaných na schéma
- Uživatelsky definované typy (alias a CLR UDT)
- Kolekce schémat XML
- Funkce oddílů
Syntaxe
Syntaxe vypadá takto:
sys.dm_sql_referenced_entities ( ' [ název_schématu. ] název_referenční_entity ' , '' ) ::={ OBJEKT | DATABASE_DDL_TRIGGER | SERVER_DDL_TRIGGER }
Příklad 1 – Základní příklad
Zde je příklad použití:
USE Test;SELECT název referenčního_schématu AS [Schéma], název referenční_entity AS Entita, vedlejší název referenční_třídy, třída referenced_class_desc AS, is_select_all, is_all_columns_foundFROM sys.dm_sql_referenced_entities ( 'dbo>ECT,J');
Výsledek:
+----------+------------+------------+--------- ---------+-----------------+---------------------- --+| Schéma | Entita | Vedlejší | třída | is_select_all | is_all_columns_found ||----------+------------+-------------+---------- --------+-----------------+----------------------- -|| dbo | Klient | NULL | OBJECT_OR_COLUMN | 1 | 1 || dbo | Klient | Kód klienta | OBJECT_OR_COLUMN | 1 | 1 || dbo | Klient | Jméno | OBJECT_OR_COLUMN | 1 | 1 || dbo | Klient | Příjmení | OBJECT_OR_COLUMN | 1 | 1 || NULL | klientský kód | NULL | TYP | 0 | 0 |+----------+------------+------------+----------- --------+-----------------+----------------------- -+
Zde získám všechny entity, na které se odkazuje v dbo.uspGetClient
uložené procedury. V tomto případě existuje pět entit.
První je tabulka s názvem „Klient“. Další tři jsou všechny sloupce v této tabulce. Posledním je uživatelsky definovaný alias datový typ nazvaný „clientcode“.
Můžeme také vidět, že první čtyři se používají v příkazu select, který používá hvězdičku (*
) zástupný znak pro výběr všech sloupců (protože jejich is_select_all
je nastaven na 1
).
Zde je skutečná definice použitá k vytvoření uložené procedury, kterou analyzujeme:
VYTVOŘENÍ POSTUPU [dbo].[uspGetClient] @ClientCode clientcode ASSELECT * FROM [dbo].[Client]WHERE ClientCode =@ClientCode;
Ano, je to velmi jednoduchá uložená procedura, ale pro naše účely je ideální. Můžeme vidět všechny odkazované entity, jak je vrátila sys.dm_sql_referenced_entities()
.
Můžeme také vidět, že procedura se skládá z jediného SELECT
dotaz, který používá zástupný znak hvězdička k výběru všech sloupců.
Příklad 2 – Odstraňte „Vybrat vše“ (*
)
Změňme uloženou proceduru tak, aby nepoužívala zástupný znak hvězdička k výběru všech sloupců.
ZMĚNIT POSTUP [dbo].[uspGetClient] @ClientCode klientský kód ASSELECT Jméno, PříjmeníFROM [dbo].[Klient]WHERE ClientCode =@ClientCode;
Nyní tedy explicitně vrací sloupce „Jméno“ a „Příjmení“. Nebyly nalezeny žádné zástupné znaky.
Nyní spusťte sys.dm_sql_referenced_entities()
znovu:
USE Test;SELECT název referenčního_schématu AS [Schéma], název referenční_entity AS Entita, vedlejší název referenční_třídy, třída referenced_class_desc AS, is_select_all, is_all_columns_foundFROM sys.dm_sql_referenced_entities ( 'dbo>ECT,J');
Výsledek:
+----------+------------+------------+--------- ---------+-----------------+---------------------- --+| Schéma | Entita | Vedlejší | třída | is_select_all | is_all_columns_found ||----------+------------+-------------+---------- --------+-----------------+----------------------- -|| dbo | Klient | NULL | OBJECT_OR_COLUMN | 0 | 1 || dbo | Klient | Kód klienta | OBJECT_OR_COLUMN | 0 | 1 || dbo | Klient | Jméno | OBJECT_OR_COLUMN | 0 | 1 || dbo | Klient | Příjmení | OBJECT_OR_COLUMN | 0 | 1 || NULL | klientský kód | NULL | TYP | 0 | 0 |+----------+------------+------------+----------- --------+-----------------+----------------------- -+
Tentokrát is_select_all
sloupec zobrazuje 0
na všech řádcích.
Příklad 3 – Odkazování na neexistující entitu
Co když vaše entita odkazuje na neexistující entitu?
Co když například váš kolega zahodí sloupec, na který ve skutečnosti odkazuje uložená procedura, a pak spustíte sys.dm_sql_referenced_entities()
proti této uložené proceduře?
Pojďme to zjistit.
ALTER TABLE [dbo].[Klient] DROP COLUMN LastName;
Právě jsem vypustil LastName
sloupec z mé tabulky.
Nyní spusťte sys.dm_sql_referenced_entities()
znovu:
SELECT referenced_schema_name AS [Schéma], referenced_entity_name AS Entita, referenced_minor_name AS Minor, referenced_class_desc AS Class, is_select_all, is_all_columns_foundFROM sys.dm_sql_referenced_entities ( 'dbo.usp'ECTpreClient>');'Výsledek:
Zpráva 207, Úroveň 16, Stav 1, Postup uspGetClient, Řádek 4Neplatný název sloupce 'Příjmení'. Zpráva 2020, Úroveň 16, Stav 1, Řádek 3 Závislosti hlášené pro entitu "dbo.uspGetClient" nemusí obsahovat odkazy na všechny sloupce . Je to buď proto, že entita odkazuje na objekt, který neexistuje, nebo z důvodu chyby v jednom nebo více příkazech v entitě. Před opětovným spuštěním dotazu se ujistěte, že v entitě nejsou žádné chyby a že existují všechny objekty, na které entita odkazuje.Příklad 4 – Zahodit celý stůl
Pojďme zjistit, co se stane, když zahodíme celý stůl.
Klient DROP TABLE;Tabulka byla zrušena.
Spusťte
sys.dm_sql_referenced_entities()
:SELECT referenced_schema_name AS [Schéma], referenced_entity_name AS Entita, referenced_minor_name AS Minor, referenced_class_desc AS Class, is_select_all, is_all_columns_foundFROM sys.dm_sql_referenced_entities ( 'dbo.usp'ECTpreClient>');'Výsledek:
Zpráva 2020, úroveň 16, stav 1, řádek 2 Závislosti hlášené pro entitu "dbo.uspGetClient" nemusí obsahovat odkazy na všechny sloupce. Je to buď proto, že entita odkazuje na objekt, který neexistuje, nebo z důvodu chyby v jednom nebo více příkazech v entitě. Před opětovným spuštěním dotazu se ujistěte, že v entitě nejsou žádné chyby a že existují všechny objekty, na které entita odkazuje.Příklad 5 – Vrátit všechny sloupce
Společnost Microsoft výslovně nedoporučuje používat hvězdičku (
*
), chcete-li vybrat všechny sloupce ze zobrazení a funkcí dynamické správy (z tohosys.dm_sql_referenced_entities()
je jeden). Důvodem je, že jejich schémata a data, která vracejí, se mohou v budoucích verzích SQL Serveru změnit. To by mohlo mít za následek přidání sloupců na konec seznamu sloupců v budoucích verzích, což by mohlo zkomplikovat vaši aplikaci, pokud se při výběru všech sloupců spoléháte na hvězdičku.Zde je příklad, který to dělá:používá hvězdičku (
*
) a vyberte všechny sloupce zsys.dm_sql_referenced_entities()
. Dělám to pouze proto, abych vám ukázal, jaké sloupce jsou skutečně vráceny z této funkce (alespoň v SQL Server 2019).SELECT *FROM sys.dm_sql_referenced_entities ( 'dbo.uspGetClient', 'OBJECT');Výsledek (při použití vertikálního výstupu):
-[ RECORD 1 ]--------------------------referencing_minor_id | 0referenced_server_name | NULLreferenced_database_name | NULLreferenced_schema_name | dboreferenced_entity_name | Clientreferenced_minor_name | NULLreferenced_id | 434100587referenced_minor_id | 0referenced_class | 1referenced_class_desc | OBJECT_OR_COLUMNis_caller_dependent | 0is_ambiguous | 0is_selected | 1is_aktualizováno | 0is_select_all | 0is_all_columns_found | 1is_insert_all | 0is_incomplete | 0-[ ZÁZNAM 2 ]-------------------------referencing_minor_id | 0referenced_server_name | NULLreferenced_database_name | NULLreferenced_schema_name | dboreferenced_entity_name | Clientreferenced_minor_name | ClientCodereferenced_id | 434100587referenced_minor_id | 1referenced_class | 1referenced_class_desc | OBJECT_OR_COLUMNis_caller_dependent | 0is_ambiguous | 0is_selected | 1is_aktualizováno | 0is_select_all | 0is_all_columns_found | 1is_insert_all | 0is_incomplete | 0-[ ZÁZNAM 3 ]-------------------------referencing_minor_id | 0referenced_server_name | NULLreferenced_database_name | NULLreferenced_schema_name | dboreferenced_entity_name | Clientreferenced_minor_name | FirstNamereferenced_id | 434100587referenced_minor_id | 2referenced_class | 1referenced_class_desc | OBJECT_OR_COLUMNis_caller_dependent | 0is_ambiguous | 0is_selected | 1is_aktualizováno | 0is_select_all | 0is_all_columns_found | 1is_insert_all | 0is_incomplete | 0-[ ZÁZNAM 4 ]-------------------------referencing_minor_id | 0referenced_server_name | NULLreferenced_database_name | NULLreferenced_schema_name | dboreferenced_entity_name | Clientreferenced_minor_name | LastNamereferenced_id | 434100587referenced_minor_id | 3referenced_class | 1referenced_class_desc | OBJECT_OR_COLUMNis_caller_dependent | 0is_ambiguous | 0is_selected | 1is_aktualizováno | 0is_select_all | 0is_all_columns_found | 1is_insert_all | 0is_incomplete | 0-[ ZÁZNAM 5 ]-------------------------referencing_minor_id | 0referenced_server_name | NULLreferenced_database_name | NULLreferenced_schema_name | NULLreferenced_entity_name | clientcodereferenced_minor_name | NULLreferenced_id | 257referenced_minor_id | 0referenced_class | 6referenced_class_desc | TYPEis_caller_dependent | 0is_ambiguous | 0is_selected | 0is_aktualizováno | 0is_select_all | 0is_all_columns_found | 0is_insert_all | 0is_incomplete | 0 (ovlivněno 5 řádků)Oficiální dokumentace
Podrobnější informace a příklady naleznete v části
sys.dm_sql_referenced_entities
na webu společnosti Microsoft.