Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Referenzierte Entitäten in SQL Server suchen:sys.dm_sql_referenced_entities

In SQL Server können Sie sys.dm_sql_referenced_entities() verwenden systemdynamische Verwaltungsfunktion, um eine Liste aller benutzerdefinierten Entitäten zu erhalten, auf die in der Definition einer bestimmten Entität namentlich verwiesen wird.

Mit anderen Worten, es gibt eine Liste aller benutzerdefinierten Entitäten zurück, von denen eine bestimmte Entität abhängt.

Insbesondere berichtet es über die folgenden Entitätstypen, auf die von der angegebenen verweisenden Entität verwiesen wird:

  • Schemagebundene Entitäten
  • Nicht schemagebundene Entitäten
  • Datenbank- und serverübergreifende Entitäten
  • Abhängigkeiten auf Spaltenebene von schemagebundenen und nicht schemagebundenen Entitäten
  • Benutzerdefinierte Typen (Alias ​​und CLR UDT)
  • XML-Schemasammlungen
  • Partitionsfunktionen

Syntax

Die Syntax lautet wie folgt:

sys.dm_sql_referenced_entities (  
    ' [ schema_name. ] referencing_entity_name ' ,
    '  ' )  
  
 ::=  
{  
    OBJECT  
  | DATABASE_DDL_TRIGGER  
  | SERVER_DDL_TRIGGER  
}

Beispiel 1 – Einfaches Beispiel

Hier ist ein Verwendungsbeispiel:

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');

Ergebnis:

+----------+------------+------------+------------------+-----------------+------------------------+
| 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                      |
+----------+------------+------------+------------------+-----------------+------------------------+

Hier erhalte ich alle Entitäten, die im dbo.uspGetClient referenziert werden gespeicherte Prozedur. In diesem Fall gibt es fünf Entitäten.

Die erste ist die Tabelle namens „Client“. Die nächsten drei sind alle Spalten innerhalb dieser Tabelle. Der letzte ist ein benutzerdefinierter Alias-Datentyp namens „clientcode“.

Wir können auch sehen, dass die ersten vier in einer Select-Anweisung verwendet werden, die das Sternchen (* ) Platzhalter, um alle Spalten auszuwählen (weil ihre is_select_all auf 1 gesetzt ist ).

Hier ist die tatsächliche Definition, die verwendet wird, um die gespeicherte Prozedur zu erstellen, die wir analysieren:

CREATE PROCEDURE [dbo].[uspGetClient] @ClientCode clientcode AS
SELECT * 
FROM [dbo].[Client]
WHERE ClientCode = @ClientCode;

Ja, es ist eine sehr einfache gespeicherte Prozedur, aber für unsere Zwecke ist sie ideal. Wir können alle referenzierten Entitäten sehen, wie sie von sys.dm_sql_referenced_entities() zurückgegeben werden .

Wir können auch sehen, dass die Prozedur aus einem einzigen SELECT besteht Abfrage, die das Sternchen als Platzhalter verwendet, um alle Spalten auszuwählen.

Beispiel 2 – Entfernen Sie „Alle auswählen“ (* )

Ändern wir die gespeicherte Prozedur so, dass sie nicht den Sternchen-Platzhalter verwendet, um alle Spalten auszuwählen.

ALTER PROCEDURE [dbo].[uspGetClient] @ClientCode clientcode AS
SELECT 
    FirstName,
    LastName
FROM [dbo].[Client]
WHERE ClientCode = @ClientCode;

Daher gibt es jetzt explizit die Spalten „FirstName“ und „LastName“ zurück. Keine Wildcards gefunden.

Führen Sie nun sys.dm_sql_referenced_entities() aus nochmal:

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');

Ergebnis:

+----------+------------+------------+------------------+-----------------+------------------------+
| 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                      |
+----------+------------+------------+------------------+-----------------+------------------------+

Diesmal ist is_select_all Spalte zeigt 0 in allen Zeilen.

Beispiel 3 – Referenzieren einer nicht existierenden Entität

Was ist, wenn Ihre Entität auf eine nicht existierende Entität verweist?

Was ist zum Beispiel, wenn Ihr Kollege eine Spalte löscht, die tatsächlich von einer gespeicherten Prozedur referenziert wird, und Sie dann sys.dm_sql_referenced_entities() ausführen gegen diese gespeicherte Prozedur?

Finden wir es heraus.

ALTER TABLE [dbo].[Client] 
DROP COLUMN LastName;

Ich habe einfach den LastName weggelassen Spalte aus meiner Tabelle.

Führen Sie nun sys.dm_sql_referenced_entities() aus nochmal:

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');

Ergebnis:

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.

Beispiel 4 – Löschen Sie die gesamte Tabelle

Lassen Sie uns herausfinden, was passiert, wenn wir die gesamte Tabelle löschen.

DROP TABLE Client;

Die Tabelle wurde gelöscht.

Führen Sie sys.dm_sql_referenced_entities() aus :

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');

Ergebnis:

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.

Beispiel 5 – Alle Spalten zurückgeben

Microsoft rät ausdrücklich davon ab, das Sternchen (* ), um alle Spalten aus dynamischen Verwaltungsansichten und -funktionen auszuwählen (darunter sys.dm_sql_referenced_entities()). ist ein). Dies liegt daran, dass sich ihre Schemas und die von ihnen zurückgegebenen Daten in zukünftigen Versionen von SQL Server ändern können. Dies könnte dazu führen, dass in zukünftigen Versionen Spalten am Ende der Spaltenliste hinzugefügt werden, was Ihre Anwendung durcheinander bringen könnte, wenn Sie sich auf das Sternchen verlassen, um alle Spalten auszuwählen.

Das heißt, hier ist ein Beispiel, das genau das tut:verwendet das Sternchen (* ), um alle Spalten aus sys.dm_sql_referenced_entities() auszuwählen . Ich mache das nur, um Ihnen zu zeigen, welche Spalten tatsächlich von dieser Funktion zurückgegeben werden (zumindest in SQL Server 2019).

SELECT *
FROM sys.dm_sql_referenced_entities (
    'dbo.uspGetClient', 
    'OBJECT');

Ergebnis (bei vertikaler Ausgabe):

-[ 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)

Offizielle Dokumentation

Ausführlichere Informationen und Beispiele finden Sie unter sys.dm_sql_referenced_entities auf der Microsoft-Website.