sys.dm_sql_referenced_entities (Transact-SQL)

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

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

  • 绑定到架构的实体

  • 非绑定到架构的实体

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

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

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

  • XML 架构集合

  • 分区函数

适用范围:SQL Server(SQL Server 2008 到当前版本)。

语法

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_name 的数据类型为 nvarchar(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 语法约定 (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 架构中的用户定义函数还是带有名为 GetOrder() 的方法、类型为 UDT 且名为 Sales 的列。

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

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

对于绑定到架构的引用始终为 0。

is_selected

bit

1 = 选中了对象或列。

适用于:SQL Server 2012 到 SQL Server 2014。

is_updated

bit

1 = 修改了对象或列。

适用于:SQL Server 2012 到 SQL Server 2014。

is_select_all

bit

1 = 对象用于 SELECT * 子句中(仅限对象级)。

适用于:SQL Server 2012 到 SQL Server 2014。

is_all_columns_found

bit

1 = 可以找到对象的所有列依赖关系。

0 = 找不到对象的列依赖关系。

适用于:SQL Server 2012 到 SQL Server 2014。

异常

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

  • 指定了系统对象。

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

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

  • 传递了无效参数。

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

无法解析列依赖关系时,返回错误 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 AdventureWorks2012;
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 AdventureWorks2012;
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.返回列依赖关系

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

USE AdventureWorks2012;
GO
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,指示存在无法发现的列。

USE AdventureWorks2012;
GO
IF OBJECT_ID ( 'dbo.Table1', 'U' ) IS NOT NULL 
    DROP TABLE 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 1The 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.演示动态依赖关系维护

下面的示例扩展了示例 D,以显示依赖关系的动态维护。 该示例首先重新创建在示例 D 中删除的 Table1。 sys.dm_sql_referenced_entities 与指定为引用实体的存储过程一起再次运行。 结果集显示返回了两个表及其各自在存储过程中定义的列。 此外,is_all_columns_found 列为所有对象和列返回 1。

USE AdventureWorks2012;
GO
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 值更新 Employee 表的 NationalIDNumber、BirthDate, MaritalStatus 和 Gender 列。 另一个存储过程 upsLogError 在 TRY…CATCH 块中定义,以便捕获任何执行错误。 is_selected、is_updated 和 is_select_all 列返回与如何在引用对象中使用这些对象和列有关的信息。 进行了修改的表和列由 is_updated 列中的 1 指示。 仅选择 BusinessEntityID 列,既不选择、也不修改存储过程 uspLogError。

适用于:SQL Server 2012 到 SQL Server 2014。

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)