sys.dm_sql_referenced_entities (Transact-SQL)

为指定的引用实体的定义中按名称引用的每个用户定义实体返回一行。当称为“被引用的实体”的一个用户定义实体按名称显示在称为“引用实体”的另一个用户定义实体的持久化 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_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。

异常

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

  • 指定了系统对象。

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

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

  • 传递了无效参数。

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

无法解析列依赖关系时,返回错误 2020。此错误不会阻止查询返回对象级依赖关系。有关详细信息,请参阅排除 SQL 依赖关系的故障

注释

可以在任何数据库的上下文中执行此函数以返回引用服务器级 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 的带编号的存储过程将不会作为引用实体或被引用的实体进行跟踪。

有关详细信息,请参阅了解 SQL 依赖关系

权限

要求对 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 AdventureWorks;
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 AdventureWorks;
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 AdventureWorks;
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 显示一行。因为 Table1 不存在,所以列依赖关系无法解析,并返回错误 2020。

USE AdventureWorks;
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
FROM sys.dm_sql_referenced_entities ('dbo.Proc1', 'OBJECT');
GO

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

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

USE AdventureWorks;
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
FROM sys.dm_sql_referenced_entities ('dbo.Proc1', 'OBJECT');
GO
DROP TABLE Table1, Table2;
DROP PROC Proc1;
GO

下面是结果集。

referenced_id, table_name, column_name

-------------  ----------- -----------

2139154566     Table1      NULL

2139154566     Table1      a

2139154566     Table1      b

2139154566     Table1      c

2707154552     Table2      NULL

2707154552     Table2      c1

2707154552     Table2      c2

更改历史记录

更新的内容

从“备注”部分中删除了“不为 CLR 表值函数跟踪列依赖关系”这句话。

更正了 referencing_entity_name 参数的数据类型。