Share via


Problembehandlung bei SQL-Abhängigkeiten

In diesem Thema werden häufige Objektabhängigkeitsprobleme und ihre Lösungen beschrieben.

Die dynamische Management-Funktion "sys.dm_sql_referenced_entities" gibt keine Abhängigkeiten auf Spaltenebene zurück

Die Systemfunktion sys.dm_sql_referenced_entities meldet jede Abhängigkeit auf Spaltenebene für schemagebundene Verweise. Die Funktion meldet z. B. alle Abhängigkeiten auf Spaltenebene für eine indizierte Sicht, da für eine indizierte Sicht Schemabindung erforderlich ist. Wenn die Entität, auf die verwiesen wird, jedoch nicht schemagebunden ist, werden Spaltenabhängigkeiten nur gemeldet, wenn alle Anweisungen, in denen auf die Spalten verwiesen wird, gebunden werden können. Anweisungen können nur erfolgreich gebunden werden, wenn alle Objekte vorhanden sind, wenn die Anweisungen analysiert werden. Wenn eine in der Entität definierte Anweisung nicht gebunden werden kann, werden Spaltenabhängigkeiten nicht gemeldet, und die Spalte referenced_minor_id gibt 0 zurück. Wenn Spaltenabhängigkeiten nicht aufgelöst werden können, wird Fehler 2020 ausgelöst. Dieser Fehler verhindert nicht, dass die Abfrage Abhängigkeiten auf Objektebene zurückgibt.

Lösung

Korrigieren Sie alle in der Meldung vor Fehler 2020 identifizierten Fehler. Im folgenden Codebeispiel wird z. B. die Sicht Production.ApprovedDocuments für die Spalten Title, ChangeNumber und Status in der Tabelle Production.Document definiert. Die Systemfunktion sys.dm_sql_referenced_entities wird für die Objekte und Spalten abgefragt, von denen die ApprovedDocuments-Sicht abhängig ist. Da die Sicht nicht mit der WITH SCHEMA_BINDING-Klausel erstellt wird, können die Spalten, auf die in der Sicht verwiesen wird, in der Tabelle geändert werden, auf die verwiesen wird. Im Beispiel wird die Spalte ChangeNumber in der Tabelle Production.Document geändert, indem sie in TrackingNumber umbenannt wird. Die Katalogsicht wird erneut für die ApprovedDocuments-Sicht abgefragt. Es ist jedoch keine Bindung an alle in der Sicht definierten Spalten möglich. Die Fehler 207 und 2020 werden zurückgegeben und geben das Problem an. Um das Problem zu beheben, muss die Sicht geändert so werden, dass der neue Name der Spalte angegeben wird.

USE AdventureWorks;
GO
CREATE VIEW Production.ApprovedDocuments
AS
    SELECT Title, ChangeNumber, Status
    FROM Production.Document
    WHERE Status = 2;
GO
SELECT referenced_schema_name AS schema_name
    ,referenced_entity_name AS table_name
    ,referenced_minor_name AS referenced_column
FROM sys.dm_sql_referenced_entities ('Production.ApprovedDocuments', 'OBJECT');
GO
EXEC sp_rename 'Production.Document.ChangeNumber', 'TrackingNumber', 'COLUMN';
GO
SELECT referenced_schema_name AS schema_name
    ,referenced_entity_name AS table_name
    ,referenced_minor_name AS referenced_column
FROM sys.dm_sql_referenced_entities ('Production.ApprovedDocuments', 'OBJECT');
GO

Die Abfrage gibt die folgenden Fehlermeldungen zurück:

Meldung 207, Ebene 16, Status 1, Prozedur ApprovedDocuments, Zeile 3

Ungültiger Spaltenname 'ChangeNumber'.

Meldung 2020, Ebene 16, Status 1, Zeile 1

Die für die Entität "Production.ApprovedDocuments" gemeldeten Abhängigkeiten beinhalten keine Verweise auf Spalten. Dies hängt entweder damit zusammen, dass die Entität auf ein Objekt verweist, das nicht vorhanden ist, oder mit einem Fehler in einer oder mehreren Anweisungen in der Entität. Bevor Sie die Abfrage erneut ausführen, stellen Sie sicher, dass die Entität keine Fehler enthält und dass alle Objekte, auf die die Entität verweist, vorhanden sind.

Im folgenden Beispiel wird der Spaltenname in der Sicht korrigiert.

USE AdventureWorks;
GO
ALTER VIEW Production.ApprovedDocuments
AS
    SELECT Title,TrackingNumber, Status
    FROM Production.Document
    WHERE Status = 2;
GO

Spalte "is_ambiguous" meldet inkonsistente Werte für benutzerdefinierte Funktionen

Es scheint möglicherweise, dass der Wert in der Spalte is_ambiguous für benutzerdefinierte Funktionen inkonsistent ist. Die Spalte is_ambiguous in der Katalogsicht sys.sql_expression_dependencies und dynamischen Funktion sys.dm_sql_referenced_entities gibt an, dass der Verweis auf die Entität mehrdeutig ist. Dies bedeutet, dass die Entität zur Laufzeit in eine benutzerdefinierte Funktion, in einen benutzerdefinierten Typ (UDT) oder in einen XQuery-Verweis auf eine Spalte des Typs xml aufgelöst werden kann. Abhängig vom Verweis auf die benutzerdefinierte Funktion kann der Entitätstyp eindeutig oder nicht eindeutig sein. Dies kann dazu führen, dass die Spalte is_ambiguous in einem Fall auf 1 (wahr) und in einem anderen Fall auf 0 (falsch) festgelegt ist. Nehmen Sie die folgende gespeicherte Prozedur als Beispiel:

CREATE PROCEDURE dbo.p1 
AS
    SELECT Sales.GetOrder() FROM t1;
    SELECT Sales.GetOrder();

In der ersten SELECT-Anweisung ist unklar, ob Sales.GetOrder() eine benutzerdefinierte Funktion im Sales-Schema oder eine Spalte mit dem Namen Sales und dem Typ UDT mit einer Methode mit dem Namen GetOrder() ist. In diesem Fall wird die Spalte is_ambiguous für die Entität Sales.GetOrder(), auf die verwiesen wird, auf 1 festgelegt. In der zweiten SELECT-Anweisung ist der Verweis auf Sales.GetOrder() eindeutig. Aufgrund der Syntax kann es sich nur um einen Verweis auf eine benutzerdefinierte Funktion handeln. In diesem Fall wird die Spalte is_ambiguous auf 0 festgelegt. Durch dieses Verhalten kann der Eindruck entstehen, dass der in der Spalte is_ambiguous gemeldete Wert inkonsistent ist. Wenn Sie wissen, wie der Wert in der Spalte is_ambiguous bestimmt wird, können Sie die gemeldeten Werte besser nachvollziehen.

Die Spalte is_ambiguous wird in den folgenden Fällen auf 0 (falsch) festgelegt:

  • Es ist eindeutig, dass sich der Verweis auf eine benutzerdefinierte Funktion bezieht. Dies bedeutet, dass die Abfrage an eine benutzerdefinierte Funktion gebunden wird und keine Spalten-UDT-Methode oder Spalte vom Typ xml mit diesem Namen vorhanden ist.

  • Es ist eindeutig, dass der Verweis sich auf eine Spalten-UDT-Methode bezieht. Dies bedeutet, dass eine Spalte mit dieser UDT-Methode vorhanden ist, während keine benutzerdefinierte Funktion oder Spalte vom Typ xml mit diesem Namen vorhanden ist.

Die Spalte is_ambiguous wird in den folgenden Fällen auf 1 (wahr) festgelegt:

  • Es ist keine benutzerdefinierte Funktion, Spalten-UDT-Methode oder Spalte vom Typ xml mit dem Namen vorhanden, auf den verwiesen wird.

  • Der Name, auf den verwiesen wird, ist für mehrere Entitäten vorhanden. Es könnten z. B. eine benutzerdefinierte Funktion und eine Spalten-UDT-Methode den gleichen Namen aufweisen.

Bei Entitäten, die von sich aus mehrdeutig sind, ist es möglich, dass die referenced_database_name-Spalte und die referenced_schema_name-Spalte ungültig sind. Ziehen Sie z. B. die folgende benutzerdefinierte Funktion in Betracht:

CREATE FUNCTION GetNextEmpHierarchyId (@empname varchar(25))
RETURNS hierarchyid
AS
BEGIN
    RETURN 
(
    SELECT h.empid.GetDescendant((SELECT MAX(h1.empid)  
                                  FROM dbo.Employees AS h1  
                                  WHERE h1.empid.GetAncestor(1) = h.empid), NULL)
    FROM dbo.Employees AS h  
    WHERE h.empname = @empname  
)  
END;

Die Spalten referenced_database_name und referenced_schema_name sind aufgrund der Aufrufe der hierarchyid-UDT-Methode für die Funktion ungültig. Es ist nicht eindeutig, ob die Verweise auf h.empid.GetDescendant und h1.empid.GetAncestor sich auf eine Entität mit einem dreiteiligen Namen (Datenbank.Schema.Objekt) oder eine UDT-Methode (Tabelle.Spalte.Methode) beziehen.

Lösung

Es ist keine Benutzeraktion erforderlich.

Spalte "referenced_id" wird für datenbankübergreifende Abhängigkeiten nicht gemeldet

Die Spalte referenced_id wird nie für datenbankübergreifende Verweise in der sys.sql_expression_dependencies-Katalogsicht aufgelöst. Der Datenbankname und der Schemaname werden nur aufgezeichnet, wenn der Name explizit angegeben wird. Wird beispielsweise MyDB.MySchema.MyTable angegeben, werden der Datenbankname und der Schemaname aufgezeichnet; wird dagegen MyDB..MyTable angegeben, wird nur der Name der Datenbank aufgezeichnet.

referenced_id wird für datenbankübergreifende Verweise nur dann in der sys.dm_sql_referenced_entities-Systemfunktion gemeldet, wenn die Entität, auf die verwiesen wird, erfolgreich gebunden werden kann. Beim Binden können u. a. aus den folgenden Gründen Fehler auftreten:

  • Die Datenbank ist offline.

  • Die Entität, auf die verwiesen wird, ist in der Datenbank nicht vorhanden.

Lösung

Überprüfen Sie, dass die Datenbank online ist, und dass die Entität, auf die verwiesen wird, in der Datenbank vorhanden ist.

Spalte "referenced_id" ist für Entitäten, auf die innerhalb der Datenbank verwiesen wird, NULL

Die sys.dm_sql_referenced_entities-Systemfunktion und die sys.sql_expression_dependencies-Systemsicht melden die ID aller schemagebundenen Entitäten, auf die verwiesen wird. Die Spalte referenced_id ist jedoch für nicht schemagebundene Verweise in der Datenbank NULL, wenn die ID der Entität, auf die verwiesen wird, nicht ermittelt werden kann. Dies kann in folgenden Situationen der Fall sein:

  • Die Entität, auf die verwiesen wird, ist in der Datenbank nicht vorhanden.

  • Namensauflösung hängt vom Aufrufer ab. In diesem Fall wird die Spalte is_caller_dependent auf 1 festgelegt.

Lösung

Überprüfen Sie, dass die Entität, auf die verwiesen wird, in der Datenbank vorhanden ist. Erstellen Sie die Entität, wenn sie nicht gefunden werden kann. Falls die Entität vorhanden ist, stellen Sie sicher, dass die folgenden Bedingungen erfüllt sind:

  • Der Name der Entität, auf die verwiesen wird, enthält keine Schreibfehler.

  • Der angegebene Name erfüllt die Sortierungsanforderungen der Datenbank. Wenn eine Datenbank eine Sortierung verwendet, die nach Groß-/Kleinschreibung unterscheidet, muss der angegebene Name der Schreibung des Objekts genau entsprechen. Die ID des Objekts SalesHistory wird z. B. in einer Datenbank, in der bei der Sortierung Groß- und Kleinschreibung unterschieden werden, nicht gefunden, wenn es als saleshistory angegeben wird.

  • Der Schemaname des Objekts wurde angegeben. Ein zweiteiliger Name (schema_name.object_name) ist erforderlich, wenn das Objekt sich nicht im Standardschema des Aufrufers, dem sys-Schema oder dem dbo-Schema befindet.

Ändern Sie die Definition der verweisenden Entität, sodass sie die oben genannten Anforderungen erfüllt.

Wenn die Entität, auf die verwiesen wird, aufruferabhängig ist, ändern Sie die Definition der verweisenden Entität, indem Sie einen zweiteiligen Namen für die Entität angeben, auf die verwiesen wird. Weitere Informationen zu aufruferabhängigen Verweisen finden Sie unter Berichten von SQL-Abhängigkeiten.

Abhängigkeitsinformationen werden für Objekte in der Masterdatenbank nicht gemeldet

SQL-Abhängigkeiten für in der Masterdatenbank erstellte benutzerdefinierte Entitäten werden erstellt und verwaltet. Wenn SQL-Abhängigkeiten für eine Entität nicht gemeldet werden, führen Sie folgende Schritte aus:

  • Stellen Sie sicher, dass die Entität einen gültigen Typ zur Abhängigkeitsnachverfolgung aufweist.

    Abhängigkeitsinformationen werden nicht für alle Benutzerobjekte verfolgt. Eine Liste von Entitätstypen, für die Abhängigkeitsinformationen erstellt und verwaltet werden, finden Sie unter Grundlegendes zu SQL-Abhängigkeiten.

  • Stellen Sie sicher, dass die Entität nicht als Systemobjekt markiert ist.

    Fragen Sie die Entität in der Spalte is_ms_shipped in der sys.objects-Katalogsicht ab. Wenn diese Spalte auf 1 festgelegt ist, handelt es sich bei dieser Entität um ein mit SQL Server geliefertes Systemobjekt oder um ein benutzerdefiniertes Objekt, das geändert wurde, um ein Systemobjekt zu imitieren, indem diese Spalte manuell auf 1 festgelegt wurde.

Lösung

Wenn der Typ des Objekts nicht unterstützt wird, sind keine Abhängigkeitsinformationen verfügbar.

Abhängigkeiten von Systemobjekten werden nicht verfolgt. Wenn die Entität benutzerdefiniert ist, muss die Spalte is_ms_shipped auf 0 zurückgesetzt werden, wenn SQL Server Abhängigkeiten für die Entität erstellen und verwalten soll.