1

我在我的一个数据库上启用了 CDC 功能。现在我在 cdc 表中有下表数据

MemberID            LastName      __$operation
1                   David         4   
1                   Dave          4
2                   Jimmy         4
2                   Test          4

现在我的问题是我必须查询 cdc 表并获取所有成员的最新行(最近更新的值)。例如查询将返回

MemberID            LastName      __$operation
1                   Dave          4
2                   Test          4
4

5 回答 5

2

除了 _ $operation 列之外,还有 _ $start_lsn 和 __$seq_val 列。由这两个订购应该可以让您到达那里。

于 2014-02-06T11:20:28.273 回答
1

您不仅可以通过 _$operations 确定 CDC。如果您想正确使用其他列字段:

__$start_lsn
__$end_lsn
__$seqval
__$update_mask
于 2014-02-06T14:38:28.277 回答
1

所以我不是 100% 确定我理解您的要求,但是如果您需要表中所有成员的最新值,则忽略 CDC 表并只查询表本身,因为这是所有最新值所在的位置毕竟。

如果您需要查看某个时间段内所有已更改的成员的最新值,则应使用 cdc.fn_cdc_get_net_changes_(capture_instance) 函数,详细说明如下:

cdc.fn_cdc_get_net_changes

这允许您指定捕获期间的开始和结束日期(通过允许您将 LSN 映射到实际时间的 sys.fn_cdc_map_time_to_lsn 函数),然后它将在此期间将净更改输出到表中。

cdc.fn_cdc_get_net_changes_(capture_instance) 更改是根据您的表名生成的,因此您没有指定这是什么,我将其称为 dbo_members,请根据需要更改,这里是如何获取列表的示例使用上面详述的函数在最后一天内所有更改的成员的最新值:

DECLARE @begin_time DATETIME ,
    @end_time DATETIME ,
    @begin_lsn BINARY(10) ,
    @end_lsn BINARY(10);
SELECT  @begin_time = GETDATE() - 1 ,
        @end_time = GETDATE(); 
SELECT  @begin_lsn = sys.fn_cdc_map_time_to_lsn('smallest greater than',
                                                @begin_time); 
SELECT  @end_lsn = sys.fn_cdc_map_time_to_lsn('largest less than or equal',
                                              @end_time); 
SELECT  [MemberID] ,
        [LastName]
FROM    cdc.fn_cdc_get_net_changes_dbo_members(@begin_lsn, @end_lsn, 'all') 
GO 
于 2014-02-06T15:31:54.627 回答
0

根据 steoleary,您可以简单地检查数据表中的最新值并完全忽略 CDC,但如果您正在查看值 from 和 to 的变化,那么您将需要参考 _$operation 值 3(已删除)和与 __$start_lsn 结合的 4 个(插入的)值。插入和删除的值对应于您在编写触发器时将使用的那些表。

要查看哪些列值更改为实际评估这些值的前兆,那么您可以使用 __$update_mask 列,绑定到 cdc.captured_columns 表,该表将为您提供实际的列名,通过实现 sys.fn_cdc_is_bit_set(captured_columns .column_ordinal, __$update_mask) 函数,其中结果 = 1。

欢迎来到 CDC 的古怪世界,以及尝试掌握它所需的大量深夜和咖啡因命中!

于 2015-09-08T20:07:09.493 回答
0

如果您的 cdc 系统表名是cdc.dbo_demo_ct以下查询,您将获得所需的结果:

SELECT *
FROM   (SELECT Row_number() OVER (partition BY a.MemberID ORDER BY b.tran_end_time DESC) t,
                       *
FROM   cdc.dbo_demo_ct a
  INNER JOIN cdc.lsn_time_mapping b
ON a.__$start_lsn = b.start_lsn) T
WHERE  T.t = 1
于 2016-12-26T07:44:33.217 回答