Troubleshooting SQL Dependencies
This topic describes common object dependency problems and their solutions.
The sys.dm_sql_referenced_entities system function will report any column-level dependency for schema-bound references. For example, the function will report all column-level dependencies for an indexed view because an indexed view requires schema binding. However, when the referenced entity is not schema-bound, column dependencies are reported only when all statements in which the columns are referenced can be bound. Statements can be successfully bound only if all objects exist at the time the statements are parsed. If any statement defined in the entity fails to bind, column dependencies will not be reported and the referenced_minor_id column will return 0. When column dependencies cannot be resolved, error 2020 is raised. This error does not prevent the query from returning object-level dependencies.
Correct any errors identified in the message before error 2020. For example, in the following code example the view Production.ApprovedDocuments is defined on the columns Title, ChangeNumber, and Status in the Production.Document table. The sys.dm_sql_referenced_entities system function is queried for the objects and columns on which the ApprovedDocuments view depends. Because the view is not created using the WITH SCHEMA_BINDING clause, the columns referenced in the view can be modified in the referenced table. The example alters the column ChangeNumber in the Production.Document table by renaming it to TrackingNumber. The catalog view is queried again for the ApprovedDocuments view; however it cannot bind to all the columns defined in the view. Errors 207 and 2020 are returned identifying the problem. To resolve the problem, the view must be altered to reflect the new name of the column.
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
The query returns the following error messages.
Msg 207, Level 16, State 1, Procedure ApprovedDocuments, Line 3
Invalid column name 'ChangeNumber'.
Msg 2020, Level 16, State 1, Line 1
The dependencies reported for entity "Production.ApprovedDocuments" do not include references to 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.
The following example corrects the column name in the view.
USE AdventureWorks; GO ALTER VIEW Production.ApprovedDocuments AS SELECT Title,TrackingNumber, Status FROM Production.Document WHERE Status = 2; GO
It may appear that the value reported in the column is_ambiguous is inconsistent for user-defined functions. The is_ambiguous column in the catalog view sys.sql_expression_dependencies and dynamic function sys.dm_sql_referenced_entities indicates that the reference to the entity is ambiguous. That is, the entity can resolve at run time to a user-defined function, a user-defined type (UDT), or an XQuery reference to a column of type xml. Depending on how the user-defined function is referenced, the entity type may or may not be clear, which can cause the is_ambiguous column to be set to 1 (true) in one case and to 0 (false) in another. For example, consider the following stored procedure.
CREATE PROCEDURE dbo.p1 AS SELECT Sales.GetOrder() FROM t1; SELECT Sales.GetOrder();
In the first SELECT statement, it is unclear whether Sales.GetOrder() is a user-defined function in the Sales schema or column named Sales of type UDT with a method named GetOrder(). In this case, the is_ambiguous column will be set to 1 for the referenced entity Sales.GetOrder(). In the second SELECT statement, the reference to Sales.GetOrder() is clear; based on the syntax, it can only be a reference to a user-defined function. In this case, the is_ambiguous column is set to 0. This behavior may make it appear that the value reported in the is_ambiguous column is inconsistent. Understanding how the value of the is_ambiguous column is determined can clarify the reported values.
The is_ambiguous column is set to 0 (false) when:
It is clear that the reference is to a user-defined function. That is, the query binds to a user-defined function and a column UDT method or column of type xml with that name does not exist.
It is clear that the reference is to a column UDT method. That is, a column with that UDT method exists and a user-defined function or column of type xml with the name does not.
The is_ambiguous column is set to 1 (true) when:
A user-defined function, column UDT method, or column of type xml with the referenced name does not exist.
The referenced name exists for multiple entities. For example, a user-defined function and a column UDT method have the same name.
For entities that are ambiguous in nature, it is possible that the referenced_database_name and referenced_schema_name columns are invalid. For example, consider the following user-defined function:
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;
The columns referenced_database_name and referenced_schema_name will be invalid for the function due to the hierarchyid UDT method calls. It is not clear that references to h.empid.GetDescendant and h1.empid.GetAncestor are references an entity using a three-part name (database.schema.object) or to a UDT method (table.column.method).
No user action is required.
The referenced_id column is never resolved for cross-database references in the sys.sql_expression_dependencies catalog view. The database name and schema name are recorded only when the name is explicitly specified. For example, when specified as MyDB.MySchema.MyTable, the database and schema names are recorded; however, when specified as MyDB..MyTable, only the database name is recorded.
The referenced_id is reported for cross-database references in the sys.dm_sql_referenced_entities system function only when the referenced entity can be successfully bound. Binding may fail for several reasons including the following causes:
The database is offline.
The referenced entity does not exist in the database.
Verify that the database is online and that the referenced entity exists in the database.
The sys.dm_sql_referenced_entities system function and the sys.sql_expression_dependencies system view will report the ID of any schema-bound referenced entity. However, the referenced_id column is NULL for non-schema-bound references within the database when the ID of the referenced entity cannot be determined. This can occur when:
The referenced entity does not exist in the database.
Name resolution is caller dependent. In this case, the is_caller_dependent column is set to 1.
Verify that the referenced entity exists in the database. Create the entity if it is not found, or, if the entity exists, make sure that the following requirements are met:
The referenced entity name is spelled correctly.
The specified name meets the collation requirements of the database. If the database uses a case-sensitive collation, the specified name specified must match the exact case of the object name. For example, the ID of an object named SalesHistory will not be found in a database with a case-sensitive collation if it is specified as saleshistory.
The schema name of the object is specified. A two-part name (schema_name.object_name) is required if the object is not in the default schema of the caller, the sys schema, or the dbo schema.
Modify the definition of the referencing entity to meet the above requirements.
If the referenced entity is caller dependent, modify the definition of the referencing entity by specifying a two-part name for the referenced entity. For more information about caller-dependent references, see Reporting SQL Dependencies.
SQL dependencies on user-defined entities created in the master database are created and maintained. If SQL dependencies for an entity are not reported, follow these steps:
Ensure that the entity is a valid type for dependency tracking
Dependency information is not tracked for all user objects. For a list of entity types for which dependency information is created and maintained, see Understanding SQL Dependencies.
Ensure that the entity is not marked as a system object.
Query the is_ms_shipped column for the entity in the sys.objects catalog view. If this column is set to 1, the entity is either a system object that ships with SQL Server, or it is a user-defined object that has been modified to mimic a system object by manually setting this column to 1.
If the object is of a type that is not supported, dependency information will not be available.
Dependencies on system objects are not tracked. If the entity is user-defined, the is_ms_shipped column must be reset to 0 if you want SQL Server to create and maintain dependencies on the entity.