最近,我使用虚拟 cdc 实例创建了一个解决方案(其中,无限数量的单独和不同的实例可以使用单个真实捕获实例作用于单个目标表,这是我需要克服的问题之一。
我的解决方案是使用持久化数据表从 CT 表接收数据,然后从那里处理数据。通过使用每 30 秒运行一次的作业以及存储实例名称和最后一个 LSN 的表进行设置,我可以将数据存储在同一客户端数据库或单独的公共数据库上的持久存储中(打开或关闭同一个 sql 实例)。
这使我可以随时指定清理并减少本地存储的数据量。
对于处理方面,这将需要您使用在创建实例时创建的 cdc 函数。通过使用 [$update_mask] 列,您可以确定实际的列更改,并简单地将这些值与 [$start_lsn]/ 一起提取(尽管操作 1,2 或 3/4) __$seqval,时间戳(从 LSN 获取)。
要破译 update_mask 列和时间戳,可以使用以下代码:
SELECT
[__$start_lsn] ,
[__$end_lsn] ,
[__$seqval] ,
[__$operation] ,
[__$update_mask] ,
sys.fn_cdc_map_lsn_to_time(__$start_lsn) [RowTimestamp],
reverse(stuff(reverse(
( SELECT CC.column_name + ','
FROM cdc.captured_columns CC
INNER JOIN cdc.change_tables CT ON CC.[object_id] = CT.[object_id]
WHERE capture_instance = 'MyCaptureInstanceName'
AND sys.fn_cdc_is_bit_set(CC.column_ordinal, __$update_mask) = 1
FOR
XML PATH('')
))
,1,1,'')) [ChangedColumns],
SYSDATETIME() [CopyTs]
FROM cdc.MyCaptureInstanceName_CT
WHERE [__$start_lsn] > (SELECT ISNULL(MAX(MaxLSN),0) FROM MyLogTable WHERE CaptureInstance = 'MyCaptureInstanceName')