I SQL Server kan du bruge sys.sql_expression_dependencies
systemkatalogvisning for at returnere alle afhængigheder på en brugerdefineret enhed i den aktuelle database. Dette inkluderer afhængigheder mellem indbygget kompilerede, skalære brugerdefinerede funktioner og andre SQL Server-moduler.
Du kan bruge denne visning til at:
- Returner enheder, der er afhængige af en given enhed
- Returner enheder, som en given enhed afhænger af
Så for eksempel kan du bruge det til at returnere alle objekter, der refererer til en bestemt tabel. Du kan også bruge den til at returnere alle objekter, som en specifik lagret procedure refererer til i sin kode.
Specifikt sys.sql_expression_dependencies
se rapporters afhængighedsoplysninger for følgende enheder:
- Skemabundne enheder.
- Ikke-skemabundne enheder.
- Enheder på tværs af databaser og servere. Enhedsnavne rapporteres; enheds-id'er løses dog ikke.
- Afhængigheder på kolonneniveau af skemabundne enheder. Kolonneniveauafhængigheder for ikke-skemabundne objekter kan returneres ved at bruge sys.dm_sql_referenced_entities.
- DDL på serverniveau udløses, når den er i sammenhæng med masterdatabasen.
Eksempel 1 – Alle kolonner returneret
Her er et hurtigt eksempel, der vælger alle kolonner fra sys.sql_expression_dependencies
. Dette viser os, hvilke data der rent faktisk returneres i visningen, og vi kan bruge en hvilken som helst af disse kolonner i vores forespørgsler til kun at returnere de data, vi er interesserede i.
SELECT TOP(1) * FROM sys.sql_expression_dependencies;
Resultat (ved hjælp af lodret output):
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
Dette eksempel bruger lodret output for at gøre det nemmere at se kolonnenavnene uden at skulle rulle vandret. Derfor er kolonnenavnene vist til venstre, og deres respektive værdier er til højre.
For korthedens skyld brugte jeg også TOP(1)
for at begrænse resultaterne til kun den første række.
Eksempel 2 – Find enheder, der er afhængige af en enhed
For at finde objekter, der afhænger af en given enhed, skal du bruge denne enheds referencing_id
når du vælger fra visningen.
Eksempel:
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');
Resultat:
+---------------------+-----------------+---------------------+---------------------+---------------------------+ | Referenced Server | Referenced DB | Referenced Schema | Referenced Entity | Referenced Entity Class | |---------------------+-----------------+---------------------+---------------------+---------------------------| | NULL | NULL | dbo | Client | OBJECT_OR_COLUMN | | NULL | NULL | NULL | clientcode | TYPE | +---------------------+-----------------+---------------------+---------------------+---------------------------+
Her får jeg alle entiteter, der er refereret til i uspGetClient
gemt procedure.
Her er den faktiske definition for uspGetClient
:
CREATE PROCEDURE [dbo].[uspGetClient] @ClientCode clientcode AS SELECT FirstName, LastName FROM [dbo].[Client] WHERE ClientCode = @ClientCode;
Så vi kan se, at den vælger data fra en tabel kaldet Client
, og den accepterer et argument kaldet @ClientCode
med en (brugerdefineret alias) datatype clientcode
.
Eksempel 3 – Find enheder, som en enhed er afhængig af
Du kan også skifte det rundt og få de objekter, som en given enhed afhænger af. For at gøre det, brug referenced_id
(i stedet for referencing_id
), når du vælger fra visningen.
Eksempel:
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');
Resultat:
+----------------------+----------------------------+------------------+------------+ | 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 | +----------------------+----------------------------+------------------+------------+
I dette eksempel ville jeg se, hvilke entiteter der er afhængige af Client
tabel (dvs. hvilke enheder der refererer til den tabel i deres SQL-kode).
Du vil bemærke, at jeg også valgte forskellige kolonner. Dette skyldes, at jeg leder efter information om henvisningen enhed, ikke den henviste enhed som i det foregående eksempel.
Eksempel 4 – Hent flere oplysninger
Du kan tilslutte denne visning med andre visninger og/eller tabeller for at returnere flere oplysninger.
For eksempel kan du tilslutte det med sys.objects
for at få referenceobjektets type:
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');
Resultat:
+----------------------+----------------------+----------+---------------------+------------+ | 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 | +----------------------+----------------------+----------+---------------------+------------+
I dette eksempel tilføjede jeg også COALESCE()
funktion for at returnere (n/a)
hver gang referencing_minor_id
er NULL
. Denne funktion er en af flere måder, hvorpå du kan erstatte en NULL-værdi med en streng i SQL Server.
Eksempel 5 – Cross-Database &Cross-Server Entities
Som nævnt, sql_expression_dependencies
fungerer også på enheder på tværs af databaser og på tværs af servere. Men i dette tilfælde rapporteres enhedsnavne, men enheds-id'er løses ikke.
Dette eksempel bruger nøjagtig den samme kode som med eksempel 2, bortset fra at denne gang er det til en anden enhed. Denne gang vil jeg finde enheder, der er afhængige af 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');
Resultat:
+---------------------+-----------------+---------------------+---------------------+---------------------------+ | Referenced Server | Referenced DB | Referenced Schema | Referenced Entity | Referenced Entity Class | |---------------------+-----------------+---------------------+---------------------+---------------------------| | Homer | Music | dbo | Albums | OBJECT_OR_COLUMN | +---------------------+-----------------+---------------------+---------------------+---------------------------+
I dette eksempel har den refererede server og referencedatabasen en værdi (i stedet for at være NULL som i det tidligere eksempel). Det er fordi uspGetAlbumsByArtist
lagret procedure bruger et firedelt navn til at referere til enheden på en sammenkædet server (den lagrede procedure fra det tidligere eksempel brugte ikke et firedelt navn, og den brugte heller ikke et tredelt navn til at specificere DB'en) .
I dette eksempel, Homer
er navnet på den linkede server og Music
er den database, som den lagrede procedure forespørger på.
Vi kan se dette i uspGetAlbumsByArtist
's definition:
CREATE PROCEDURE [dbo].[uspGetAlbumsByArtist] @ArtistId int AS SELECT AlbumName FROM [Homer].[Music].[dbo].[Albums] WHERE ArtistId = @ArtistId;
Officiel dokumentation
For mere detaljerede oplysninger og eksempler, se sys.sql_expression_dependencies
på Microsofts websted.
Her er en anden Microsoft-artikel, som indeholder instruktioner til at få afhængigheder via SSMS.