CHANGETABLE (Transact-SQL)

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

返回表的更改跟踪信息。 可以使用此语句返回表的所有更改或更改特定行的跟踪信息。

Transact-SQL 语法约定

语法

CHANGETABLE (  
    { CHANGES <table_name> , <last_sync_version> 
    | VERSION <table_name> , <primary_key_values> } 
    , [ FORCESEEK ] 
    )  
[AS] <table_alias> [ ( <column_alias> [ ,...n ] )  
  
<primary_key_values> ::=  
( <column_name> [ , ...n ] ) , ( <value> [ , ...n ] )  

参数

更改table_name,last_sync_version
返回自last_sync_version指定的版本以来对表所做的所有更改的跟踪信息。

table_name
是要从中获取跟踪的更改的用户定义表。 必须在表上启用更改跟踪。 可以使用由一部分、两部分、三部分或四部分构成的表名。 表名可以是表的同义词。

last_sync_version
可为 null 的 bigint 标量值。 表达式将导致语法错误。 如果值为 NULL,则返回所有跟踪的更改。 获取更改时,调用应用程序必须指定所需更改的起始点。 last_sync_version指定该点。 该函数返回在该版本之后更改的所有行的信息。 应用程序正在查询以接收版本大于 last_sync_version的更改。 通常,在获取更改之前,应用程序将调用 CHANGE_TRACKING_CURRENT_VERSION() 以获取下次需要更改时将使用的版本。 因此,该应用程序不必解释或了解实际值。 由于 调用应用程序获取last_sync_version ,因此应用程序必须保留该值。 如果应用程序丢失该值,则需要重新初始化数据。 应验证last_sync_version以确保它不是太旧,因为某些或所有更改信息可能已根据为数据库配置的保留期进行清理。 有关详细信息,请参阅CHANGE_TRACKING_MIN_VALID_VERSION(Transact-SQL)ALTER DATABASE SET 选项(Transact-SQL)。

版本 table_name, { primary_key_values }
返回指定行的最新更改跟踪信息。 主键值必须标识该行。 primary_key_values 标识主键列并指定值。 可以按任意顺序指定主键列名称。

table_name
是用户定义的从中获取更改跟踪信息的表。 必须在表上启用更改跟踪。 可以使用由一部分、两部分、三部分或四部分构成的表名。 表名可以是表的同义词。

column_name
指定一个或多个主键列的名称。 可以按任意顺序指定多个列名。

value
是主键的值。 如果有多个主键列,则必须按照与column_name列表中显示的列相同的顺序指定值。

[ FORCESEEK ]
适用于:SQL Server (从 SQL Server 2016 (13.x) SP2 CU16、SQL Server 2017 (14.x) CU24 和 SQL Server 2019 (15.x) CU11 开始)、Azure SQL 数据库和Azure SQL 托管实例

强制使用查找操作访问table_name可选参数。 在某些情况下,极少数行已更改,扫描操作仍可用于访问 table_name。 如果扫描操作引入了性能问题,请使用 FORCESEEK 参数。

[AS] table_alias [ (column_alias [ ,...n ] ] ]
为 CHANGETABLE 返回的结果提供名称。

table_alias
是 CHANGETABLE 返回的表的别名。 table_alias是必需的,并且必须是有效的标识符

column_alias
是由 CHANGETABLE 返回的列的可选列别名或列别名列表。 这使得在结果中存在重复的名称时可以自定义列名。

返回类型

table

返回值

CHANGETABLE CHANGES

指定了 CHANGES 时,返回零个或多个具有以下列的行。

列名称 数据类型 描述
SYS_CHANGE_VERSION bigint 与上次对行的更改关联的版本值
SYS_CHANGE_CREATION_VERSION bigint 与上次插入操作关联的版本值。
SYS_CHANGE_OPERATION nchar(1) 指定更改的类型:

U = 更新

I = 插入

D = 删除
SYS_CHANGE_COLUMNS varbinary(4100) 列出自 last_sync_version(基准版本)以后发生了更改的列。 请注意,计算列永远不会列为已更改。

以下任何一个条件为真时,值为 NULL:

未启用列更改跟踪。

操作是插入操作或删除操作。

在一个操作中更新了所有非主键列。 不应直接解释此二进制值。 相反,若要解释它,请使用 CHANGE_TRACKING_IS_COLUMN_IN_MASK()
SYS_CHANGE_CONTEXT varbinary(128) 更改上下文信息,可以选择使用 WITH 子句作为 INSERT、UPDATE 或 DELETE 语句的一部分进行指定。
<主键列值> 与用户表列相同 被跟踪表的主键值。 这些值在用户表中唯一标识各行。

CHANGETABLE VERSION

指定 VERSION 后,返回一个具有以下列的行。

列名称 数据类型 描述
SYS_CHANGE_VERSION bigint 与行关联的当前更改版本值。

如果在超过更改跟踪保留期的时段内没有进行更改,或者在启用更改跟踪之后未更改行,则值为 NULL。
SYS_CHANGE_CONTEXT varbinary(128) 更改可以在 INSERT、UPDATE 或 DELETE 语句中使用 WITH 子句选择指定的上下文信息。
<主键列值> 与用户表列相同 被跟踪表的主键值。 这些值在用户表中唯一标识各行。

注解

CHANGETABLE 函数通常在对表的查询的 FROM 子句中使用。

CHANGETABLE(CHANGES...)

要获取新行或修改过的行的行数据,请使用主键列将结果集与用户表联接起来。 即使由于last_sync_version值以来对同一行进行了多次更改,用户表中的每一行也只返回一行

永远不将对主键列的更改标记为更新。 如果主键值更改,则会视作删除旧值并插入新值。

如果删除一行,然后插入具有旧的主键值的行,则将更改视作对行中所有列的更新。

SYS_CHANGE_OPERATIONSYS_CHANGE_COLUMNS列返回的值相对于指定的基线(last_sync_version)。 例如,如果在版本10上执行插入操作和版本15更新操作,并且基线last_sync_version12为,则会报告更新。 如果last_sync_version8,将报告插入。 SYS_CHANGE_COLUMNS 永远不会将计算列报告为已更新。

通常,将跟踪在用户表中插入、更新或删除数据的所有操作,其中包括 MERGE 语句。

不会跟踪影响用户表数据的以下操作:

  • UPDATETEXT执行语句。 此语句已弃用,将在 SQL Server 的未来版本中删除。 但是,跟踪使用 .WRITE UPDATE 语句子句所做的更改。

  • 使用 TRUNCATE TABLE.. 某个表被截断时,将会重置与该表关联的更改跟踪版本信息,就像刚刚对该表启用了更改跟踪一样。 客户端应用程序应始终验证其上一次同步的版本。 如果表已截断,验证将会失败。

CHANGETABLE(VERSION...)

如果指定的主键不存在,则会返回空结果集。

如果更改未超过保留期(例如,清理已删除更改信息),或者自为表启用更改跟踪以来从未更改过行,则该值 SYS_CHANGE_VERSION 可能为 NULL。

权限

SELECT需要对主键列的权限以及VIEW CHANGE TRACKING由table_name>值指定的<表的权限才能获取更改跟踪信息。

示例

A. 返回数据初始同步的行

下面的示例演示了如何获取表数据的初始同步的数据。 该查询返回所有行数据及其关联的版本。 您可以随后将此数据插入或添加到要包含同步数据的系统中。

-- Get all current rows with associated version  
SELECT e.[Emp ID], e.SSN, e.FirstName, e.LastName,  
    c.SYS_CHANGE_VERSION, c.SYS_CHANGE_CONTEXT  
FROM Employees AS e  
CROSS APPLY CHANGETABLE   
    (VERSION Employees, ([Emp ID], SSN), (e.[Emp ID], e.SSN)) AS c;  

B. 列出自特定版本起进行的所有更改

下面的示例列出了从指定的版本 (@last_sync_version)) 起在表中进行的所有更改。 [Emp ID] 和 SSN 是组合主键中的列。

DECLARE @last_sync_version bigint;  
SET @last_sync_version = <value obtained from query>;  
SELECT [Emp ID], SSN,  
    SYS_CHANGE_VERSION, SYS_CHANGE_OPERATION,  
    SYS_CHANGE_COLUMNS, SYS_CHANGE_CONTEXT   
FROM CHANGETABLE (CHANGES Employees, @last_sync_version) AS C;  

°C 获取同步的所有已更改数据

下面的示例演示如何获取所有已更改数据。 此查询将更改跟踪信息与用户表联接,以便返回用户表信息。 使用 LEFT OUTER JOIN 以便为删除的行返回一行。

-- Get all changes (inserts, updates, deletes)  
DECLARE @last_sync_version bigint;  
SET @last_sync_version = <value obtained from query>;  
SELECT e.FirstName, e.LastName, c.[Emp ID], c.SSN,  
    c.SYS_CHANGE_VERSION, c.SYS_CHANGE_OPERATION,  
    c.SYS_CHANGE_COLUMNS, c.SYS_CHANGE_CONTEXT   
FROM CHANGETABLE (CHANGES Employees, @last_sync_version) AS c  
    LEFT OUTER JOIN Employees AS e  
        ON e.[Emp ID] = c.[Emp ID] AND e.SSN = c.SSN;  

D. 使用 CHANGETABLE(VERSION...) 检测冲突

下面的示例演示了如何只更新在上次同步之后未更改的行。 使用 CHANGETABLE 获取特定行的版本号。 如果行已经更新,则不进行更改,并且查询将返回有关对行的最近更改的信息。

-- @last_sync_version must be set to a valid value  
UPDATE  
    SalesLT.Product  
SET  
    ListPrice = @new_listprice  
FROM  
    SalesLT.Product AS P  
WHERE  
    ProductID = @product_id AND  
    @last_sync_version >= ISNULL (  
        (SELECT CT.SYS_CHANGE_VERSION FROM   
            CHANGETABLE(VERSION SalesLT.Product,  
            (ProductID), (P.ProductID)) AS CT),  
        0);  

另请参阅

更改跟踪函数 (Transact-SQL)
跟踪数据更改 (SQL Server)
CHANGE_TRACKING_IS_COLUMN_IN_MASK (Transact-SQL)
CHANGE_TRACKING_CURRENT_VERSION (Transact-SQL)
CHANGE_TRACKING_MIN_VALID_VERSION (Transact-SQL)