В SQL Server можете да използвате sys.dm_sql_referenced_entities()
функция за динамично управление на системата, за да получите списък с всички дефинирани от потребителя обекти, които са посочени по име, в дефиницията на даден обект.
С други думи, той връща списък с всички дефинирани от потребителя обекти, от които зависи специфичен обект.
По-конкретно, той докладва за следните типове обекти, препращани от посочения референтен обект:
- Свързани със схема обекти
- Обекти, които не са свързани със схема
- Обекти с кръстосана база данни и между сървъри
- Зависимости на ниво колона от свързани със схема и необвързани със схема обекти
- Дефинирани от потребителя типове (псевдоним и CLR UDT)
- Колекции от XML схеми
- Функции за дялове
Синтаксис
Синтаксисът е така:
sys.dm_sql_referenced_entities ( ' [ schema_name. ] referencing_entity_name ' , '' ) ::={ OBJECT | DATABASE_DDL_TRIGGER | SERVER_DDL_TRIGGER }
Пример 1 – Основен пример
Ето пример за употреба:
ИЗПОЛЗВАЙТЕ тест;ИЗБЕРЕТЕ referenced_schema_name AS [Схема], referenced_entity_name AS Entity, referenced_minor_name AS Minor, referenced_class_desc AS Class, is_select_all, is_all_columns_foundFROM sys.dm_sql_referenced_entities');Резултат:
+----------+------------+-----------+--------- ---------+----------------+--------------------- --+| Схема | Обект | Малък | Клас | is_select_all | is_all_columns_found ||----------+------------+------------+---------- --------+----------------+----------------------- -|| dbo | Клиент | NULL | OBJECT_OR_COLUMN | 1 | 1 || dbo | Клиент | Клиентски код | OBJECT_OR_COLUMN | 1 | 1 || dbo | Клиент | Име | OBJECT_OR_COLUMN | 1 | 1 || dbo | Клиент | Фамилия | OBJECT_OR_COLUMN | 1 | 1 || NULL | клиентски код | NULL | ТИП | 0 | 0 |+---------+------------+-----------+---------- --------+----------------+----------------------- -+Тук получавам всички обекти, които са посочени в
dbo.uspGetClient
съхранена процедура. В този случай има пет субекта.Първата е таблицата, наречена „Клиент“. Следващите три са всички колони в тази таблица. Последният е дефиниран от потребителя псевдоним тип данни, наречен "clientcode".
Можем също да видим, че първите четири се използват в оператор select, който използва звездичката (
*
) заместващ знак, за да изберете всички колони (защотоis_select_all
е настроен на1
).Ето действителната дефиниция, използвана за създаване на съхранената процедура, която анализираме:
СЪЗДАВАНЕ НА ПРОЦЕДУРА [dbo].[uspGetClient] @ClientCode клиентски код ASSELECT * FROM [dbo].[Client]WHERE ClientCode =@ClientCode;Да, това е много проста съхранена процедура, но е идеална за нашите цели. Можем да видим всички посочени обекти, върнати от
sys.dm_sql_referenced_entities()
.Можем също да видим, че процедурата се състои от един
SELECT
заявка, която използва заместващия знак звездичка за избор на всички колони.Пример 2 – Премахнете „Избор на всички“ (
*
)Нека променим съхранената процедура, така че да не използва заместващия знак за звездичка, за да избере всички колони.
ПРОМЕНЯ ПРОЦЕДУРА [dbo].[uspGetClient] @ClientCode клиентски код ASSELECT FirstName, LastNameFROM [dbo].[Client]WHERE ClientCode =@ClientCode;Така че сега изрично връща колоните „FirstName“ и „LastName“. Не са намерени заместващи знаци.
Сега стартирайте
sys.dm_sql_referenced_entities()
отново:ИЗПОЛЗВАЙТЕ тест;ИЗБЕРЕТЕ referenced_schema_name AS [Схема], referenced_entity_name AS Entity, referenced_minor_name AS Minor, referenced_class_desc AS Class, is_select_all, is_all_columns_foundFROM sys.dm_sql_referenced_entities');Резултат:
+----------+------------+-----------+--------- ---------+----------------+--------------------- --+| Схема | Обект | Малък | Клас | is_select_all | is_all_columns_found ||----------+------------+------------+---------- --------+----------------+----------------------- -|| dbo | Клиент | NULL | OBJECT_OR_COLUMN | 0 | 1 || dbo | Клиент | Клиентски код | OBJECT_OR_COLUMN | 0 | 1 || dbo | Клиент | Име | OBJECT_OR_COLUMN | 0 | 1 || dbo | Клиент | Фамилия | OBJECT_OR_COLUMN | 0 | 1 || NULL | клиентски код | NULL | ТИП | 0 | 0 |+---------+------------+-----------+---------- --------+----------------+----------------------- -+Този път
is_select_all
колоната показва0
на всички редове.Пример 3 – Препращане към несъществуващ обект
Ами ако вашият обект се позовава на несъществуващ обект?
Например, какво ще стане, ако вашият колега изпусне колона, която всъщност се препраща от съхранена процедура, и след това изпълните
sys.dm_sql_referenced_entities()
срещу тази съхранена процедура?Нека разберем.
ПРОМЕНЯ ТАБЛИЦА [dbo].[Клиент] ИЗПУСКАНЕ НА КОЛОНА Фамилия;Току-що изпуснах
LastName
колона от моята таблица.Сега стартирайте
sys.dm_sql_referenced_entities()
отново:SELECT referenced_schema_name AS [Схема], referenced_entity_name AS Entity, referenced_minor_name AS Minor, referenced_class_desc AS Class, is_select_all, is_all_columns_foundFROM sys.dm_sql_referenced_entities ( 'dm_sql_referenced_entities, 'dm'Cli');Резултат:
Съобщение 207, ниво 16, състояние 1, процедура uspGetClient, ред 4 Невалидно име на колона „LastName“. Msg 2020, ниво 16, състояние 1, ред 3. Зависимостите, отчетени за обект „dbo.uspGetClient“ към всички колони, може да не включват препратки . Това е или защото обектът препраща към обект, който не съществува, или поради грешка в един или повече изрази в обекта. Преди да изпълните повторно заявката, уверете се, че няма грешки в обекта и че всички обекти, на които обектът препраща, съществуват.Пример 4 – Изхвърлете цялата таблица
Нека разберем какво се случва, ако изпуснем цялата маса.
DROP TABLE Client;Таблицата е отпаднала.
Изпълнете
sys.dm_sql_referenced_entities()
:SELECT referenced_schema_name AS [Схема], referenced_entity_name AS Entity, referenced_minor_name AS Minor, referenced_class_desc AS Class, is_select_all, is_all_columns_foundFROM sys.dm_sql_referenced_entities ( 'dm_sql_referenced_entities, 'dm'Cli');Резултат:
Съобщение 2020, ниво 16, състояние 1, ред 2. Зависимостите, отчетени за обект „dbo.uspGetClient“ може да не включват препратки към всички колони. Това е или защото обектът препраща към обект, който не съществува, или поради грешка в един или повече изрази в обекта. Преди да изпълните повторно заявката, уверете се, че няма грешки в обекта и че всички обекти, на които обектът препраща, съществуват.Пример 5 – Връщане на всички колони
Microsoft изрично препоръчва да не използвате звездичката (
*
), за да изберете всички колони от динамични изгледи и функции за управление (от коитоsys.dm_sql_referenced_entities()
е един). Това е така, защото техните схеми и данните, които връщат, може да се променят в бъдещи версии на SQL Server. Това може да доведе до добавяне на колони в края на списъка с колони в бъдещи версии, което може да обърка приложението ви, ако разчитате на звездичката, за да изберете всички колони.Въпреки това, ето пример, който прави точно това:използва звездичката (
*
), за да изберете всички колони отsys.dm_sql_referenced_entities()
. Правя това само, за да ви покажа какви колони всъщност се връщат от тази функция (поне в SQL Server 2019).ИЗБЕРЕТЕ *FROM sys.dm_sql_referenced_entities ('dbo.uspGetClient', 'OBJECT');Резултат (с помощта на вертикален изход):
-[ ЗАПИС 1 ]------------------------------reference_minor_id | 0referenced_server_name | NULLиме_на_база_данни | NULLпосочено_име_на_схема | dborreferenced_entity_name | Clientreferenced_minor_name | NULLreferenced_id | 434100587referenced_minor_id | 0referenced_class | 1referenced_class_desc | OBJECT_OR_COLUMNis_caller_dependent | 0е_двусмислено | 0 е_избрано | 1 е_актуализиран | 0е_избере_всички | 0е_всички_колони_намерени | 1е_вмъкни_всички | 0 е_непълно | 0-[ ЗАПИС 2 ]------------------------------referencing_minor_id | 0referenced_server_name | NULLиме_на_база_данни | NULLпосочено_име_на_схема | dborreferenced_entity_name | Clientreferenced_minor_name | ClientCodereferenced_id | 434100587referenced_minor_id | 1посочен_клас | 1referenced_class_desc | OBJECT_OR_COLUMNis_caller_dependent | 0е_двусмислено | 0 е_избрано | 1 е_актуализиран | 0е_избере_всички | 0е_всички_колони_намерени | 1е_вмъкни_всички | 0 е_непълно | 0-[ ЗАПИС 3 ]------------------------------referencing_minor_id | 0referenced_server_name | NULLиме_на_база_данни | NULLпосочено_име_на_схема | dborreferenced_entity_name | Clientreferenced_minor_name | Име,посочено_идентификатор | 434100587referenced_minor_id | 2referenced_class | 1referenced_class_desc | OBJECT_OR_COLUMNis_caller_dependent | 0е_двусмислено | 0 е_избрано | 1 е_актуализиран | 0е_избере_всички | 0е_всички_колони_намерени | 1е_вмъкни_всички | 0 е_непълно | 0-[ ЗАПИС 4 ]------------------------------referencing_minor_id | 0referenced_server_name | NULLиме_на_база_данни | NULLпосочено_име_на_схема | dborreferenced_entity_name | Clientreferenced_minor_name | LastNamereferenced_id | 434100587referenced_minor_id | 3referenced_class | 1referenced_class_desc | OBJECT_OR_COLUMNis_caller_dependent | 0е_двусмислено | 0 е_избрано | 1 е_актуализиран | 0е_избере_всички | 0е_всички_колони_намерени | 1е_вмъкни_всички | 0 е_непълно | 0-[ ЗАПИС 5 ]------------------------------referencing_minor_id | 0referenced_server_name | NULLиме_на_база_данни | NULLпосочено_име_на_схема | NULLпосочено_име_на_същност | клиентски код, посочено_незначително_име | NULLreferenced_id | 257referenced_minor_id | 0referenced_class | 6referenced_class_desc | TYPE е_зависим от_обаждащия се | 0е_двусмислено | 0 е_избрано | 0е_актуализиран | 0е_избиране_всички | 0е_всички_колони_намерени | 0is_insert_all | 0 е_непълно | 0 (засегнати 5 реда)Официална документация
За по-подробна информация и примери вижте
sys.dm_sql_referenced_entities
на уебсайта на Microsoft.