SQL Server的以前版本在跟踪 对象 相关性 方面做的并不好。原因是所有的 对象 相关性 都是由 对象 ID来跟踪的,这意味着 对象 一开始就必须存在。但是,通过根据 对象 名称来跟踪 对象 SQL Server 2008极大地扩展了跟踪 对象 的能力,而不用再依赖ID。该方法
SQL Server的以前版本在跟踪 对象 相关性 方面做的并不好。原因是所有的 对象 相关性 都是由 对象 ID来跟踪的,这意味着 对象 一开始就必须存在。但是,通过根据 对象 名称来跟踪 对象 SQL Server 2008极大地扩展了跟踪 对象 的能力,而不用再依赖ID。该方法的好处是在一些 对象 已经从数据库中转移出去后,还可以继续跟踪 对象 ,甚至在 对象 没有建立时也可以进行跟踪。
新管理 对象
SQL Server 2008引进了两个新动态管理函数和新系统视图,用于跟踪 对象 相关性 。这两个新 对象 包括Database Engine存储的有关 相关性 的信息,这些 相关性 是在创建、更改和放弃 对象 时建立的。在一个 对象 以名称的形式出现于存储在另一个 对象 中的SQL表达式中时,一个 相关性 就会在两个 对象 之间创建。在表达式中出现的 对象 称为被引用实体,而包含SQL表达式的 对象 称为引用实体。
sys.sql_expression_dependencies
本视图含有当前数据库中用户定义的一个 对象 的每个 相关性 的一个记录。这些用户定义的 对象 可以是存储在当前数据库中的 对象 ,或者存储在不同数据库中并利用部分命名规则(databasename.schemaname.objectname)被引用的 对象 ,在不同的服务器上并 使用 四部分命名规则(servername.databasename.schemaname.objectname)通过链接服务器被引用的 对象 ,以及在特定 对象 创建时不存在的 对象 (称为延迟 对象 )。
sys.dm_sql_referenced_entities
用户在定义特定引用实体时,本函数为通过名称引用的每个用户定义的 对象 返回一个行,例如,如果视图vw_SampleView引用表Table1 的Field1、 Field2和 Field3,则将返回四行,针对被引用字段返回三行,针对表引用返回一行。
sys.dm_sql_referencing_entities
该函数为用户在当前数据库中定义的每个 对象 返回一个记录,这些 对象 通过名称引用另一个用户定义的 对象 。例如,如果视图vw_SampleView引用Table1 和 Table2,则该函数返回两个记录,针对每个表引用返回一个记录。
举例
以下示例显示了如何通过创建一些 对象 和查询新DMV在数据库内部跟踪 相关性 。利用下边的脚本创建名称为SalesHistory的表:
CREATE TABLE [dbo].[SalesHistory]( [SaleID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED, [Product] [char](150) NULL, [SaleDate] [datetime] NULL, [SalePrice] [money] NULL )
在下边的脚本中,创建了名称为dbo.usp_GetSales的存储的过程,该过程引用在以上脚本中创建的SalesHistory表: CREATE PROCEDURE dbo.usp_GetSales ( @Product VARCHAR(10) ) AS BEGIN SELECT COUNT(SaleID) AS SalesCount, SUM(SalePrice) AS SalesAmount FROM dbo.SalesHistory sh END
下边的脚本 使用 表值函型数sys.dm_sql_referenced_returns寻找所有引用SalesHistory表的 对象 。这一查询不但返回SalesHistory表的引用,还包含被引用的SalesHistory表中的字段。值得注意的是CROSS APPLY操作符的 使用 ,这是因为实体是表值型函数,而且在将字段值赋予表值型函数时需要APPLY操作符。还要注意,如果遇到引用一个不存在的实体字段, 对sys.dm_referenced_entities函数的调用会出错: SELECT ReferencedEntityName = o.name, g.referenced_entity_name, referenced_minor_name FROM sys.objects o JOIN sys.schemas s on o.schema_id = s.schema_id CROSS APPLY sys.dm_sql_referenced_entities(s.name + '.' + o.name, 'OBJECT') g WHERE referenced_entity_name = 'SalesHistory'
在下边的脚本中,创建了一个新的名称为usp_GetSalesFromArchive的存储的过程,该过程引用不存在的SalesHistoryArchive 表
CREATE PROCEDURE usp_GetSalesFromArchive ( @Product VARCHAR(10) ) AS BEGIN SELECT COUNT(SaleArchiveID) AS SalesCount, SUM(SaleArchivePrice) AS SalesAmount FROM dbo.SalesHistoryArchive sh END
现在可以利用 sys.sql_expression_dependencies系统视图寻找引用SalesHistoryArchive 表的任何 对象 。
或者,可以稍微改变该查询来寻找存储的过程usp_GetSalesFromArchive引用的表.
SELECT ReferencingObject = o.name , ReferencedObject = d.referenced_entity_name FROM sys.sql_expression_dependencies d join sys.objects o on d.referencing_id = o.object_id WHERE o.name = 'usp_GetSalesFromArchive'
结论
通过 对象 名称而不是 对象 ID跟踪 相关性 拥有诸多好处。用户可能喜欢寻找存储的过程,该过程引用并不存在的 对象 ,因为这帮助用户寻找不再 使用 或需要更新的任何存储的过程。
查看更多关于使用SQLServer2008中对象相关性的详细内容...