В SQL Server можете да използвате sys.sql_expression_dependencies
изглед на системния каталог, за да върне всички зависимости от потребителски дефиниран обект в текущата база данни. Това включва зависимости между собствено компилирани, скаларни дефинирани от потребителя функции и други модули на SQL Server.
Можете да използвате този изглед за:
- Връщане на обекти, които зависят от даден обект
- Връщане на обекти, от които зависи даден обект
Така например, можете да го използвате, за да върнете всички обекти, които препращат към конкретна таблица. Можете също да го използвате, за да върнете всички обекти, които конкретна съхранена процедура препраща в своя код.
По-конкретно, sys.sql_expression_dependencies
вижте информация за зависимостта на отчетите за следните обекти:
- Свързани към схема обекти.
- Необвързани към схема обекти.
- Обекти с кръстосана база данни и между сървъри. Отчитат се имена на субекти; обаче идентификаторите на обекти не се разрешават.
- Зависимости на ниво колона от обекти, свързани със схема. Зависимостите на ниво колона за обекти, които не са свързани със схема, могат да бъдат върнати с помощта на sys.dm_sql_referenced_entities.
- DDL на ниво сървър се задейства, когато е в контекста на основната база данни.
Пример 1 – Върнати всички колони
Ето един бърз пример, който избира всички колони от sys.sql_expression_dependencies
. Това ни показва какви данни всъщност се връщат в изгледа и можем да използваме всяка от тези колони в нашите заявки, за да върнем само данните, които ни интересуват.
SELECT TOP(1) * FROM sys.sql_expression_dependencies;
Резултат (с помощта на вертикален изход):
referencing_id | 114099447 referencing_minor_id | 0 referencing_class | 1 referencing_class_desc | OBJECT_OR_COLUMN is_schema_bound_reference | 0 referenced_class | 1 referenced_class_desc | OBJECT_OR_COLUMN referenced_server_name | NULL referenced_database_name | NULL referenced_schema_name | dbo referenced_entity_name | Client referenced_id | 434100587 referenced_minor_id | 0 is_caller_dependent | 0 is_ambiguous | 0
Този пример използва вертикален изход, за да улесни виждането на имената на колоните, без да се налага да превъртате хоризонтално. Следователно имената на колоните са изброени отляво, а съответните им стойности са отдясно.
Освен това за краткост използвах TOP(1)
за да ограничите резултатите само до първия ред.
Пример 2 – Намерете обекти, които зависят от обект
За да намерите обекти, които зависят от даден обект, използвайте referencing_id
на този обект когато избирате от изгледа.
Пример:
SELECT referenced_server_name AS [Referenced Server], referenced_database_name AS [Referenced DB], referenced_schema_name AS [Referenced Schema], referenced_entity_name AS [Referenced Entity], referenced_class_desc AS [Referenced Entity Class] FROM sys.sql_expression_dependencies WHERE referencing_id = OBJECT_ID('uspGetClient');
Резултат:
+---------------------+-----------------+---------------------+---------------------+---------------------------+ | Referenced Server | Referenced DB | Referenced Schema | Referenced Entity | Referenced Entity Class | |---------------------+-----------------+---------------------+---------------------+---------------------------| | NULL | NULL | dbo | Client | OBJECT_OR_COLUMN | | NULL | NULL | NULL | clientcode | TYPE | +---------------------+-----------------+---------------------+---------------------+---------------------------+
Тук получавам всички обекти, които са посочени в uspGetClient
съхранена процедура.
Ето действителната дефиниция за uspGetClient
:
CREATE PROCEDURE [dbo].[uspGetClient] @ClientCode clientcode AS SELECT FirstName, LastName FROM [dbo].[Client] WHERE ClientCode = @ClientCode;
Така можем да видим, че той избира данни от таблица, наречена Client
и приема аргумент, наречен @ClientCode
с (дефиниран от потребителя псевдоним) тип данни clientcode
.
Пример 3 – Намерете обекти, от които зависи един обект
Можете също да го превключите и да получите обектите, от които зависи даден обект. За да направите това, използвайте referenced_id
(вместо referencing_id
), когато избирате от изгледа.
Пример:
SELECT OBJECT_NAME(referencing_id) AS [Referencing Entity], OBJECT_NAME(referencing_minor_id) AS [Referencing Minor Entity], referencing_class_desc AS [Class], COL_NAME(referenced_id, referenced_minor_id) AS [Column] FROM sys.sql_expression_dependencies WHERE referenced_id = OBJECT_ID('Client');
Резултат:
+----------------------+----------------------------+------------------+------------+ | Referencing Entity | Referencing Minor Entity | Class | Column | |----------------------+----------------------------+------------------+------------| | uspGetClient | NULL | OBJECT_OR_COLUMN | NULL | | uspGetOrdersByClient | NULL | OBJECT_OR_COLUMN | NULL | | chkClientCode | NULL | OBJECT_OR_COLUMN | ClientCode | +----------------------+----------------------------+------------------+------------+
В този пример исках да видя кои обекти зависят от Client
таблица (т.е. кои обекти се позовават на тази таблица в своя SQL код).
Ще забележите, че и аз избрах различни колони. Това е така, защото търся информация за препратката обект, а не препратката обект като в предишния пример.
Пример 4 – Извличане на повече информация
Можете да се присъедините към този изглед с други изгледи и/или таблици, за да върнете повече информация.
Например, можете да го присъедините с sys.objects
за да получите типа на референтния обект:
SELECT OBJECT_NAME(referencing_id) AS [Referencing Entity], o.type_desc AS [Type], COALESCE(COL_NAME(referencing_id, referencing_minor_id), '(n/a)') AS [Column], referenced_entity_name AS [Referenced Entity], COALESCE(COL_NAME(referenced_id, referenced_minor_id), '(n/a)') AS [Column] FROM sys.sql_expression_dependencies AS sed INNER JOIN sys.objects AS o ON sed.referencing_id = o.object_id WHERE referenced_id = OBJECT_ID(N'Client');
Резултат:
+----------------------+----------------------+----------+---------------------+------------+ | Referencing Entity | Type | Column | Referenced Entity | Column | |----------------------+----------------------+----------+---------------------+------------| | uspGetClient | SQL_STORED_PROCEDURE | (n/a) | Client | (n/a) | | uspGetOrdersByClient | SQL_STORED_PROCEDURE | (n/a) | Client | (n/a) | | chkClientCode | CHECK_CONSTRAINT | (n/a) | Client | ClientCode | +----------------------+----------------------+----------+---------------------+------------+
В този пример добавих и COALESCE()
функция за връщане на (n/a)
винаги, когато referencing_minor_id
е NULL
. Тази функция е един от няколкото начина, по които можете да замените стойност NULL с низ в SQL Server.
Пример 5 – Кръстосана база данни и кръстосани сървърни обекти
Както споменахме, sql_expression_dependencies
също така работи върху кръстосани бази данни и междусървърни обекти. В този случай обаче имената на обекти се отчитат, но идентификаторите на обекти не се разрешават.
Този пример използва точно същия код като пример 2, с изключение на това, че този път е за различен обект. Този път искам да намеря обекти, които зависят от uspGetAlbumsByArtist
:
SELECT referenced_server_name AS [Referenced Server], referenced_database_name AS [Referenced DB], referenced_schema_name AS [Referenced Schema], referenced_entity_name AS [Referenced Entity], referenced_class_desc AS [Referenced Entity Class] FROM sys.sql_expression_dependencies WHERE referencing_id = OBJECT_ID('uspGetAlbumsByArtist');
Резултат:
+---------------------+-----------------+---------------------+---------------------+---------------------------+ | Referenced Server | Referenced DB | Referenced Schema | Referenced Entity | Referenced Entity Class | |---------------------+-----------------+---------------------+---------------------+---------------------------| | Homer | Music | dbo | Albums | OBJECT_OR_COLUMN | +---------------------+-----------------+---------------------+---------------------+---------------------------+
В този пример реферираният сървър и реферираната база данни имат стойност (вместо да са NULL, както в предишния пример). Това е така, защото uspGetAlbumsByArtist
съхранената процедура използва име от четири части за препратка към обекта на свързан сървър (съхранената процедура от предишния пример не използва име от четири части и не използва име от три части, за да посочи DB също) .
В този пример Homer
е името на свързания сървър и Music
е базата данни, която запомнената процедура отправя заявки.
Можем да видим това в uspGetAlbumsByArtist
определение на:
CREATE PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS SELECT AlbumName FROM [Homer].[Music].[dbo].[Albums] WHERE ArtistId = @ArtistId;
Официална документация
За по-подробна информация и примери вижте sys.sql_expression_dependencies
на уебсайта на Microsoft.
Ето още една статия на Microsoft, която включва инструкции за получаване на зависимости чрез SSMS.