原文:点击打开链接
2.10.1 更改跟踪
SQL Server 2008 引入了更改跟踪(Change Tracking,简称 CT)。更改跟踪是一种轻量型解决方案,它为应用程序提供了一种有效的更改跟踪机制。
通常,若要使应用程序能够查询对数据库中的数据所做的更改和访问与这些更改相关的信息,应用程序开发人员必须实现自定义更改跟踪机制。 创建这些机制通常涉及多项工作,并且常常涉及使用触发器、 timestamp 列和新表组合来存储跟踪信息,同时还会涉及使用自定义清除过程。
现在,应用程序可以使用更改跟踪来捕获以下有关对用户表所做的更改:
(1)用户表中有哪些行发生了更改? 所需的只是行已更改的事实,而不是行更改的次数或任何中间更改的值。如果应用程序需要有关所有所做更改的信息以及所更改数据的中间值,则可能适合使用变更数据捕获,而不适合使用更改跟踪。
(2)从所跟踪的用户表中直接获取最新的数据。
(3)判断某行是否已更改?当在同一事务中进行更改时,必须提供并记录行已更改的事实以及有关这一更改的信息。
为了跟踪表的更改信息,用户表必须有主键,然后才能启用更改跟踪。
2.10.2 对数据库启用更改跟踪
可以通过SSMS 对用户数据库启用改跟踪功能。
T-SQL 脚本如下:
USE [master] GO ALTER DATABASE [DB01] SET CHANGE_TRACKING = ON (CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON) GO |
可以在启用更改跟踪时指定 CHANGE_RETENTION 和 AUTO_CLEANUP 选项,并且可以在启用更改跟踪后随时更改这些值。
2.10.3 对表启用更改跟踪
对于要跟踪的每个表都必须启用更改跟踪。可以通过SSMS 对用户表的更改跟踪功能。
T-SQL 脚本如下:
USE [DB01] GO ALTER TABLE [dbo].[SalesOrder] ENABLE CHANGE_TRACKING WITH (TRACK_COLUMNS_UPDATED = OFF) GO |
启用跟踪后,将会为表中受 DML 操作影响的所有行保留更改跟踪信息。
当 TRACK_COLUMNS_UPDATED 选项设为 ON 时,SQL Server 数据库引擎会将有关哪些列已更新的额外信息存储到内部更改跟踪表中。列跟踪使应用程序可以只同步那些已更新的列。这可以提高效率和性能。但是,由于保留列跟踪信息增加了一些额外的存储开销,因而默认情况下此选项设为 OFF。
2.10.4 为数据库或表禁用更改跟踪
必须首先为所有启用了更改跟踪的表禁用更改跟踪,然后才能将数据库的更改跟踪设为 OFF。 若要确定数据库中哪些表启用了更改跟踪,请使用 sys.change_tracking_tables 目录视图。
当数据库中没有用于跟踪更改的表时,便可以禁用数据库的更改跟踪。
USE [DB01] GO ALTER TABLE [dbo].[SalesOrder] DISABLE CHANGE_TRACKING GO USE [master] GO ALTER DATABASE [DB01] SET CHANGE_TRACKING = OFF GO |
2.10.5 使用更改跟踪
启用了更改跟踪的数据库具有一个版本计数器;在对启用了更改跟踪的表进行更改时,该计数器会随之递增。每个更改的行都有一个关联的版本号。将请求发送到应用程序以查询更改时,将调用一个函数以提供版本号。该函数返回在该版本之后所做的所有更改的相关信息。从某种意义上讲,更改跟踪版本在概念上与 rowversion 数据类型类似。
下例返回当前的版本号。
DECLARE @synchronization_version bigint; SET @synchronization_version = CHANGE_TRACKING_CURRENT_VERSION(); SELECT @synchronization_version AS synchronization_version |
下例查询最新的数据,SYS_CHANGE_VERSION 是数据库中任何行的变更时产生的版本号。
SELECT t.*, CT.* FROM dbo.SalesOrder t CROSS APPLY CHANGETABLE(VERSION dbo.SalesOrder,(SalesOrderID), (t.SalesOrderID) ) AS CT |
下例返回指定的 last_sync_version 后改变的最新数据,不包括被删除的数据行。
DECLARE @last_sync_version bigint; SET @last_sync_version = 2; SELECT t.*, CT.* FROM dbo.SalesOrder t INNER JOIN CHANGETABLE(CHANGES dbo.SalesOrder,@last_sync_version) AS CT ON t.SalesOrderID=CT.SalesOrderID |
下例返回指定的 last_sync_version 后所有的数据变化,包括被删除的数据行。
DECLARE @last_sync_version bigint; SET @last_sync_version = 2; SELECT t.*, CT.* FROM dbo.SalesOrder t RIGHT OUTER JOIN CHANGETABLE(CHANGES dbo.SalesOrder,@last_sync_version) AS CT ON t.SalesOrderID=CT.SalesOrderID |
参考资料
《关于更改跟踪 (SQL Server)》 https://docs.microsoft.com/zh-cn/sql/relational-databases/track-changes/about-change-tracking-sql-server