因此,我们开始探索在我们的一个生产数据库上使用变更数据捕获。我们想知道每次更改的日期时间。通读演练和教程等似乎标准方法是使用 LSN 与cdc.lsn_time_mapping
系统表相关。这种方法有效,但在谈论每天成千上万的更改时不是很简单也不是很高效。
在测试环境中,我对更改跟踪表进行了以下调整。我发表了一条ALTER TABLE
声明,在名为的末尾添加一列并将其设为[__ChangeDateTime]
默认值GetDate()
。该方法似乎有效,更改跟踪仍然正常运行,正在捕获日期时间。 但是乱搞系统表让我有点紧张。
如果这不是微软从一开始就添加的系统字段,他们一定有他们的理由。由于他们改为选择 LSN 到 cdc.lsn_time_mapping 方法,我是否通过这种方式创建自己的 hack 来解决问题?
更新:
在测试期间发现 GetDate() 有时不足以满足我们的需求 - 多个更改共享同一时间。建议使用sysdatetime() 和 datetime2将值移到纳秒级。显然只有 2008+ 的选项。
请记住,CDC 使用日志读取器代理来填充更改表。为什么这很重要?通过这种机制,行在更改表中的显示与基表中所做的更改异步。
实际上可以记录 3 个不同的时间点,按时间倒序排列:
cdc.lsn_time_mapping
)。所以首先要明确你想要记录的内容。通常我们会关心#2 或#3。
如果 LSN 映射机制 (#2) 对您来说表现不够好,唯一受支持的替代方法是向基表添加一列并自己填充它 (#3)。
关于更改内部表,作为一项政策,我认为最好避免在有支持的替代方案时使用内部表。您最不想看到的是一个重要的生产系统出现故障,需要致电产品支持,并因此而被拒绝提供服务。不要介意它可能破坏事物(升级)或因为意外而被破坏的问题(关闭 CDC,然后再次打开,如另一个答案中所述)。
一个实际的例子:
我要给出的唯一警告是,当 CDC 被禁用时,这些表会自动删除。当您重新启用它时,该列不会自动重新创建
受加雷斯回答的启发,这里有一个较短的版本。
DECLARE
如果您需要创建VIEW
(DECLARE
is not allowed inVIEW
) ,这不使用which is great在前面的答案的基础上,我创建了这个脚本,它将查看所有 CDC 表并显示表名和最后更新: