sys.dm_sql_referenced_entities (Transact-SQL)

适用于: SQL Server Azure SQL 数据库 Azure SQL 托管实例

为 SQL Server 中指定引用实体的定义中按名称引用的每个用户定义的实体返回一行。 当一个名为引用实体的用户定义的实体(称为引用实体)在另一个用户定义的实体(称为引用实体)的持久化 SQL 表达式中显示两个实体之间的依赖关系。 例如,如果存储过程是指定的引用实体,则此函数会返回该存储过程中引用的所有用户定义实体,例如表、视图、用户定义类型 (UDT) 或其他存储过程。

可以使用此动态管理函数报告指定的引用实体引用的以下类型的实体:

  • 绑定到架构的实体

  • 非绑定到架构的实体

  • 跨数据库和跨服务器的实体

  • 绑定到架构的实体和非绑定到架构的实体的列级依赖关系

  • 用户定义类型(别名和 CLR UDT)

  • XML 架构集合

  • 分区函数

语法

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

参数

[ schema_name. ] referencing_entity_name
是引用实体的名称。 当引用类为 OBJECT 时,需要schema_name。

schema_name.referencing_entity_namenvarchar(517)。

<> referencing_class ::= { OBJECT |DATABASE_DDL_TRIGGER |SERVER_DDL_TRIGGER }
指定的引用实体的类。 每个语句只能指定一个类。

<> referencing_class为 nvarchar(60)。

返回的表

列名称 数据类型 描述
referencing_minor_id int 引用实体为列时的列 ID;否则为 0。 不可为 null。
referenced_server_name sysname 被引用的实体的服务器的名称。

此列是为通过指定由四个部分组成的有效名称所生成的跨服务器依赖关系填充的。 有关多部分名称的信息,请参阅 Transact-SQL 语法约定

对于非绑定到架构的依赖关系,如果引用实体时没有指定由四个部分组成的名称,此列为 NULL。

对于绑定到架构的实体,此列为 NULL,原因在于它们必须在同一数据库中,因而只能使用由两个部分 (schema.object) 组成的名称定义。
referenced_database_name sysname 被引用的实体的数据库的名称。

此列是为通过指定由三个部分或四个部分组成的有效名称生成的跨数据库或跨服务器引用填充的。

对于非绑定到架构的引用,当使用由一个部分或两个部分组成的名称指定时,此列为 NULL。

对于绑定到架构的实体,此列为 NULL,原因在于它们必须在同一数据库中,因而只能使用由两个部分 (schema.object) 组成的名称定义。
referenced_schema_name sysname 被引用的实体所属的架构。

对于非绑定到架构的引用,如果实体被引用时没有指定架构名称,此列为 NULL。

对于绑定到架构的引用,此列永远不会为 NULL。
referenced_entity_name sysname 被引用的实体的名称。 不可为 null。
referenced_minor_name sysname 引用的实体是列时是列名;否则是 NULL。 例如,referenced_minor_name 在列出所引用的实体自身的行中是 NULL。

当列在引用实体中按名称标识时,或者当 SELECT * 语句中使用了父实体时,被引用的实体为列。
referenced_id int 被引用的实体的 ID。 当 referenced_minor_id 不为 0 时,referenced_id 是该列被定义时所在的实体。

对于跨服务器的引用,此列始终为 NULL。

对于跨数据库的引用,当由于数据库脱机或实体无法绑定而无法确定 ID 时,此列为 NULL。

对于数据库内的引用,如果无法确定 ID,则为 NULL。 对于非架构绑定引用,在数据库中不存在引用实体或名称解析依赖于调用方时,无法解析 ID。 在后一种情况下,is_caller_dependent设置为 1。

对于绑定到架构的引用,此列永远不会为 NULL。
referenced_minor_id int 引用的实体是列时是列 ID;否则是 0。 例如,referenced_minor_is 在列出所引用的实体本身的行中是 0。

对于非绑定到架构的引用,只有当可以绑定所有被引用的实体时才报告列依赖关系。 如果无法绑定任何被引用的实体,则不报告列级依赖关系,并且 referenced_minor_id 是 0。 请参见示例 D。
referenced_class tinyint 被引用的实体的类。

1 = 对象或列

6 = 类型

10 = XML 架构集合

21 = 分区函数
referenced_class_desc nvarchar(60) 对被引用的实体的类的说明。

OBJECT_OR_COLUMN

TYPE

XML_SCHEMA_COLLECTION

PARTITION_FUNCTION
is_caller_dependent bit 指示被引用的实体的架构绑定发生于运行时,因此实体 ID 的解析依赖于调用方的架构。 当被引用的实体为存储过程、扩展存储过程或在 EXECUTE 语句中调用的用户定义函数时,将会出现这种情况。

1 = 被引用的实体依赖调用方并在运行时解析。 在这种情况下,referenced_id 为 NULL。

0 = 被引用的实体 ID 不依赖调用方。 对于绑定到架构的引用、显式指定架构名称的跨数据库和跨服务器的引用,始终为 0。 例如,对格式为 EXEC MyDatabase.MySchema.MyProc 的实体的引用不依赖于调用方。 但是,格式为 EXEC MyDatabase..MyProc 的引用依赖调用方。
is_ambiguous bit 指示引用为不明确引用,并可以在运行时解析为用户定义函数、用户定义类型 (UDT) 或者对 xml 类型的列的 xquery 引用。 例如,假定语句 SELECT Sales.GetOrder() FROM Sales.MySales 是在存储过程中定义的。 在执行存储过程之前,并不知道 Sales.GetOrder()Sales 架构中的用户定义函数还是带有名为 Sales 的方法、类型为 UDT 且名为 GetOrder() 的列。

1 = 引用的是用户定义函数还是使用用户定义类型 (UDT) 方法的列,这一点是不明确的。

0 = 引用是明确的,或者在调用函数时可以成功绑定实体。

对于绑定到架构的引用始终为 0。
is_selected bit 1 = 选中了对象或列。
is_updated bit 1 = 修改了对象或列。
is_select_all bit 1 = 对象用于 SELECT * 子句中(仅限对象级)。
is_all_columns_found bit 1 = 可以找到对象的所有列依赖关系。

0 = 找不到对象的列依赖关系。
is_insert_all bit 1 = 对象在不包含列列表的 INSERT 语句中使用(仅对象级别)。

此列已在 SQL Server 2016 中添加。
is_incomplete bit 1 = 对象或列有绑定错误且不完整。

此列已在 SQL Server 2016 SP2 中添加。

异常

在满足以下任一条件时将返回空的结果集:

  • 指定了系统对象。

  • 当前数据库中不存在指定的实体。

  • 指定的实体不引用任何实体。

  • 传递了无效参数。

当指定的引用实体是带编号的存储过程时,返回错误。

无法解析列依赖关系时,返回错误 2020。 此错误不会阻止查询返回对象级依赖关系。

注解

可以在任何数据库的上下文中执行此函数以返回引用服务器级 DDL 触发器的实体。

下表列出了为其创建和维护依赖关系信息的实体类型。 不为规则、默认值、临时表、临时存储过程或系统对象创建或维护依赖关系信息。

实体类型 引用实体 被引用的实体
是*
查看​
Transact-SQL 存储过程**
CLR 存储过程
Transact-SQL 用户定义函数
CLR 用户定义函数
CLR 触发器(DML 和 DDL)
Transact-SQL DML 触发器
Transact-SQL 数据库级 DDL 触发器
Transact-SQL 服务器级 DDL 触发器
扩展的存储过程
队列
同义词
类型(别名和 CLR 用户定义类型)
XML 架构集合
分区函数

* 仅当表在计算列定义、CHECK 约束或 DEFAULT 约束中引用 Transact-SQL 模块、用户定义类型或 XML 架构集合时,才会将该表作为引用实体进行跟踪。

** 整数值大于 1 的带编号的存储过程将不会作为引用实体或被引用的实体进行跟踪。

权限

要求对 sys.dm_sql_referenced_entities 拥有 SELECT 权限并对引用实体拥有 VIEW DEFINITION 权限。 默认情况下,SELECT 权限授予 public。 要求对数据库拥有 VIEW DEFINITION 权限或 ALTER DATABASE DDL TRIGGER 权限(当引用实体为数据库级 DDL 触发器时)。 当引用实体为服务器级 DDL 触发器时,要求对服务器拥有 VIEW ANY DEFINITION 权限。

示例

A. 返回由数据库级 DDL 触发器引用的实体

下面的示例返回数据库级 DDL 触发器 ddlDatabaseTriggerLog 引用的实体(表和列)。

USE AdventureWorks2022;  
GO  
SELECT
        referenced_schema_name,
        referenced_entity_name,
        referenced_minor_name,
        referenced_minor_id,
        referenced_class_desc
    FROM
        sys.dm_sql_referenced_entities (
            'ddlDatabaseTriggerLog',
            'DATABASE_DDL_TRIGGER')
;
GO  

B. 返回对象引用的实体

下面的示例返回用户定义函数 dbo.ufnGetContactInformation 引用的实体。

USE AdventureWorks2022;  
GO  
SELECT
        referenced_schema_name,
        referenced_entity_name,
        referenced_minor_name,
        referenced_minor_id,
        referenced_class_desc,
        is_caller_dependent,
        is_ambiguous
    FROM
        sys.dm_sql_referenced_entities (
            'dbo.ufnGetContactInformation',
            'OBJECT')
;
GO  

°C 返回列依赖项

下面的示例创建具有定义为列 Table1c 之和的计算列 a 的表 b。 然后 sys.dm_sql_referenced_entities 视图被调用。 该视图返回两行,每行针对计算列中定义的一列。

CREATE TABLE dbo.Table1 (a int, b int, c AS a + b);  
GO  
SELECT
        referenced_schema_name AS schema_name,  
        referenced_entity_name AS table_name,  
        referenced_minor_name  AS referenced_column,  
        COALESCE(
            COL_NAME(OBJECT_ID(N'dbo.Table1'),
            referencing_minor_id),
            'N/A') AS referencing_column_name  
    FROM
        sys.dm_sql_referenced_entities ('dbo.Table1', 'OBJECT')
;
GO

-- Remove the table.  
DROP TABLE dbo.Table1;  
GO  

结果集如下。

schema_name table_name referenced_column referencing_column  
----------- ---------- ----------------- ------------------  
dbo         Table1     a                 c  
dbo         Table1     b                 c  

D. 返回非绑定到架构的列依赖关系

下面的示例删除 Table1 并创建 Table2 和存储过程 Proc1。 该过程引用 Table2 以及不存在的表 Table1。 视图 sys.dm_sql_referenced_entities 和指定为引用实体的存储过程一起运行。 结果集对于 Table1 显示一行,对于 Table2 显示 3 行。 因为 Table1 不存在,所以列依赖关系无法解析,并返回错误 2020。 is_all_columns_found 列为 Table1 返回 0,指示存在无法发现的列。

DROP TABLE IF EXISTS dbo.Table1;
GO  
CREATE TABLE dbo.Table2 (c1 int, c2 int);  
GO  
CREATE PROCEDURE dbo.Proc1 AS  
    SELECT a, b, c FROM Table1;  
    SELECT c1, c2 FROM Table2;  
GO  
SELECT
        referenced_id,
        referenced_entity_name AS table_name,
        referenced_minor_name  AS referenced_column_name,
        is_all_columns_found
    FROM
        sys.dm_sql_referenced_entities ('dbo.Proc1', 'OBJECT');
GO  

结果集如下。

referenced_id table_name   referenced_column_name  is_all_columns_found  
------------- ------------ ----------------------- --------------------  
935674381     Table2       NULL                    1  
935674381     Table2       C1                      1  
935674381     Table2       C2                      1  
NULL          Table1       NULL                    0  

Msg 2020, Level 16, State 1, Line 1
The dependencies reported for entity "dbo.Proc1" 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.

E. 演示动态依赖关系维护

此示例 E 假定已运行示例 D。 示例 E 显示依赖项是动态维护的。 此示例执行以下操作:

  1. 在示例 D 中删除的重新创建 Table1
  2. 运行 Then sys.dm_sql_referenced_entities 时,将使用指定为引用实体的存储过程再次运行。

结果集显示返回两个表及其在存储过程中定义的相应列。 此外,is_all_columns_found 列为所有对象和列返回 1。

CREATE TABLE Table1 (a int, b int, c AS a + b);  
GO   
SELECT
        referenced_id,
        referenced_entity_name AS table_name,
        referenced_minor_name  AS column_name,
        is_all_columns_found
    FROM
        sys.dm_sql_referenced_entities ('dbo.Proc1', 'OBJECT');
GO  
DROP TABLE Table1, Table2;  
DROP PROC Proc1;  
GO  

结果集如下。

referenced_id table_name   referenced_column_name  is_all_columns_found  
------------- ------------ ----------------------- --------------------  
935674381     Table2       NULL                    1 
935674381     Table2       c1                      1 
935674381     Table2       c2                      1 
967674495     Table1       NULL                    1 
967674495     Table1       a                       1  
967674495     Table1       b                       1  
967674495     Table1       c                       1  

F. 返回对象或列的用法

下面的示例返回存储过程 HumanResources.uspUpdateEmployeePersonalInfo 的对象和列依赖关系。 此过程根据指定的BusinessEntityID值更新列BirthDate,``MaritalStatusNationalIDNumberGenderEmployee表。 另一个存储过程是在 upsLogError TRY 中定义的...CATCH 块用于捕获任何执行错误。 is_selectedis_updatedis_select_all 列返回与如何在引用对象中使用这些对象和列有关的信息。 进行了修改的表和列由 is_updated 列中的 1 指示。 仅选择 BusinessEntityID 列,既不选择、也不修改存储过程 uspLogError

USE AdventureWorks2022;
GO
SELECT
        referenced_entity_name AS table_name,
        referenced_minor_name  AS column_name,
        is_selected,  is_updated,  is_select_all
    FROM
        sys.dm_sql_referenced_entities(
            'HumanResources.uspUpdateEmployeePersonalInfo',
            'OBJECT')
;

结果集如下。

table_name    column_name         is_selected is_updated is_select_all  
------------- ------------------- ----------- ---------- -------------  
uspLogError   NULL                0           0          0  
Employee      NULL                0           1          0  
Employee      BusinessEntityID    1           0          0  
Employee      NationalIDNumber    0           1          0  
Employee      BirthDate           0           1          0  
Employee      MaritalStatus       0           1          0  
Employee      Gender              0           1          0

另请参阅

sys.dm_sql_referencing_entities (Transact-SQL)
sys.sql_expression_dependencies (Transact-SQL)