cdc.fn_cdc_get_net_changes_<capture_instance> (Transact-SQL)

针对指定 LSN 范围内每个已更改的源行返回一个净更改行。也就是说,如果在 LSN 范围内源行具有多项更改,则该函数将返回反映该行最终内容的单一行。例如,如果事务在源表中插入一行,并且 LSN 范围内的后续事务更新了该行中的一个或多个列,则该函数将只返回一行,其中包含多个更新的列值。

此枚举函数是在对某源表启用变更数据捕获并指定净跟踪时创建的。若要启用净跟踪,源表必须具有主键或唯一索引。此函数名称是派生的,采用 cdc.fn_cdc_get_net_changes_capture_instance 格式,其中 capture_instance 是对变更数据捕获启用源表时为捕获实例指定的值。有关详细信息,请参阅 sys.sp_cdc_enable_table (Transact-SQL)

主题链接图标Transact-SQL 语法约定

语法

cdc.fn_cdc_get_net_changes_capture_instance ( from_lsn , to_lsn , '<row_filter_option>' )

<row_filter_option> ::=
{ all
 | all with mask
 | all with merge
}

参数

  • from_lsn
    LSN,它表示要包含在结果集中的 LSN 范围的低端点。from_lsn 的数据类型为 binary(10)。

    结果集中仅包含 cdc.[capture_instance]_CT 更改表中 __$start_lsn 中的值大于或等于 from_lsn 的行。

  • to_lsn
    LSN,它表示要包含在结果集中的 LSN 范围的高端点。to_lsn 的数据类型为 binary(10)。

    结果集中仅包含 cdc.[capture_instance]_CT 更改表中 __$start_lsn 中的值小于或等于 from_lsn 或等于 to_lsn 的行。

  • <行筛选选项> ::= { all | all with mask | all with merge }
    控制元数据列的内容和结果集中所返回的行的选项。可以是下列选项之一:

    • all
      返回对元数据列 __$start_lsn 和 __$operation 中的行所做最后更改的 LSN 以及应用这些行所需的操作。列 __$update_mask 始终为 NULL。

    • all with mask
      返回对元数据列 __$start_lsn 和 __$operation 中的行所做最后更改的 LSN 以及应用这些行所需的操作。另外,当更新操作返回 (__$operation = 4) 时,更新操作中修改过的已捕获列会在 __$update_mask 中返回的值中进行标记。

    • all with merge
      返回对元数据列 __$start_lsn 中的行所做的最终更改的 LSN。列 __$operation 为下列两个值之一:1 表示删除,5 表示应用更改所需的操作是插入或更新。列 __$update_mask 始终为 NULL。

      由于用来确定给定更改的精确操作的逻辑会增加查询的复杂性,所以,在只需指出应用更改数据所需的操作是插入还是更新但不必明确区分这两者时,使用该选项可提高查询性能。在可直接使用合并操作的目标环境(如 SQL Server 2008 环境)中,此选项非常有用。

返回的表

列名

数据类型

说明

__$start_lsn

binary(10)

与更改的提交事务关联的 LSN。

在同一事务中提交的所有更改将共享同一个提交 LSN。例如,如果对源表的更新操作在两行中修改了两列,则更改表将包含四行,每一行均具有相同的 __$start_lsn 值。

__$seqval

binary(10)

用于对事务内的行更改进行排序的序列值。

__$operation

int

标识将更改数据行应用到目标数据源所需的数据操作语言 (DML) 操作。

如果 row_filter_option 参数的值为 all 或 all with mask,则此列中的值可以是以下值之一:

1 = 删除

2 = 插入

4 = 更新

如果 row_filter_option 参数的值为 all with merge,则此列中的值可以是以下值之一:

1 = 删除

5 = 插入或更新

值为 5 表示行是否已存在以及是否只需要更新是未知的,或者行当前是否存在以及是否必须插入是未知的。

__$update_mask

varbinary(128)

位掩码,为捕获实例标识的每个已捕获列均对应于一个位。如果 __$operation = 1 或 2,则该值将所有已定义的位设置为 1。如果 __$operation = 3 或 4,则仅将对应于已更改列的位设置为 1。

<<已捕获的源表列>>

不定

函数返回的其余列是在创建捕获实例时源表中标识为已捕获列的那些列。如果已捕获列的列表中未指定任何列,则将返回源表中的所有列。

权限

要求具有 sysadmin 固定服务器角色或 db_owner 固定数据库角色的成员身份。对于所有其他用户,要求对源表中的所有已捕获列具有 SELECT 权限;如果已定义捕获实例的访问控制角色,则还要求具有该数据库角色的成员身份。当调用方没有查看源数据的权限时,函数将返回错误 208(对象名无效)。

注释

如果指定的 LSN 范围不在捕获实例的更改跟踪时间线范围之内,则函数将返回错误 208(对象名无效)。

示例

以下示例使用函数 cdc.fn_cdc_get_net_changes_HR_Department 报告在特定时间间隔内对源表 HumanResources.Department 所做的净更改。

首先,GETDATE 函数用于标记时间间隔的开始。在将多个 DML 语句应用到源表后,再次调用 GETDATE 函数可标识时间间隔的结束。然后使用函数 sys.fn_cdc_map_time_to_lsn 将时间间隔映射到由 LSN 值绑定的变更数据捕获查询范围。最后,查询函数 cdc.fn_cdc_get_net_changes_HR_Department 以获取该时间间隔内对源表所做的净更改。请注意,插入后又删除的行在函数返回的结果集中不会出现。这是因为在查询窗口中先添加然后又删除的行在时间间隔内对源表不生成任何净更改。在运行此示例之前,必须先运行 sys.sp_cdc_enable_table (Transact-SQL) 中的示例 B。

USE AdventureWorks;
GO
DECLARE @begin_time datetime, @end_time datetime, @from_lsn binary(10), @to_lsn binary(10);
-- Obtain the beginning of the time interval.
SET @begin_time = GETDATE() -1;
-- DML statements to produce changes in the HumanResources.Department table.
INSERT INTO HumanResources.Department (Name, GroupName)
VALUES (N'MyDept', N'MyNewGroup');

UPDATE HumanResources.Department
SET GroupName = N'Resource Control'
WHERE GroupName = N'Inventory Management';

DELETE FROM HumanResources.Department
WHERE Name = N'MyDept';

-- Obtain the end of the time interval.
SET @end_time = GETDATE();
-- Map the time interval to a change data capture query range.
SET @from_lsn = sys.fn_cdc_map_time_to_lsn('smallest greater than or equal', @begin_time);
SET @to_lsn = sys.fn_cdc_map_time_to_lsn('largest less than or equal', @end_time);

-- Return the net changes occurring within the query window.
SELECT * FROM cdc.fn_cdc_get_net_changes_HR_Department(@from_lsn, @to_lsn, 'all');