更改数据捕获和 __$update_mask 二进制文件

RTh*_*mas 9 sql-server-2008 change-data-capture

我们正在使用 CDC 来捕获对生产表所做的更改。更改的行正在导出到数据仓库 (informatica)。我知道 __$update_mask 列存储了以 varbinary 形式更新的列。我也知道我可以使用各种 CDC 函数从该掩码中找出这些列是什么。

我的问题是这个。任何人都可以为我定义该掩码背后的逻辑,以便我们可以识别仓库中已更改的列吗?由于我们在服务器外部进行处理,因此我们无法轻松访问那些 MSSQL CDC 函数。我宁愿自己在代码中分解面具。SQL 端的 cdc 函数的性能对于此解决方案是有问题的。

简而言之,我想从 __$update_mask 字段中手动识别更改的列。

更新:

作为替代方案,也可以将已更改列的人类可读列表发送到仓库。我们发现这可以以远高于我们原始方法的性能来执行。

以下 CLR 对此问题的回答符合此备选方案,并包括为未来访问者解释掩码的详细信息。然而,对于相同的最终结果,使用 XML PATH 接受的答案是最快的。

RTh*_*mas 11

这个故事的寓意是......测试,尝试其他事情,先大后小,总是假设有更好的方法。

和我上一个答案一样在科学上很有趣。我决定尝试另一种方法。我记得我可以使用 XML PATH('') 技巧进行连接。由于我知道如何从上一个答案中的 capture_column 列表中获取每个更改列的序号,因此我认为值得测试 MS 位函数是否可以更好地满足我们的需要。

SELECT __$update_mask ,
        ( 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 = 'dbo_OurTableName'
                    AND sys.fn_cdc_is_bit_set(CC.column_ordinal,
                                              PD.__$update_mask) = 1
        FOR
          XML PATH('')
        ) AS changedcolumns
FROM    cdc.dbo_MyTableName PD
Run Code Online (Sandbox Code Playgroud)

它比所有 CLR 更简洁(虽然没有那么有趣),仅将方法返回到本机 SQL 代码。而且,drum roll.... 在不到一秒的时间内返回相同的结果。由于生产数据每秒增加 100 倍。

出于科学目的,我将另一个答案保留 - 但就目前而言,这是我们的正确答案。