0

从时态表加载数据时,我们使用标准方法 - 通过将周期开始列值与最新加载时间戳进行比较来获取上次加载后发生的所有更改。

根据MSDN 文档(同样适用于更新和删除)

INSERTS:在 INSERT 上,系统根据系统时钟将 SysStartTime 列的值设置为当前事务的开始时间(在 UTC 时区),并将 SysEndTime 列的值分配为最大值 9999- 12-31。这会将行标记为打开。

假设我们在 开始一些长时间运行的事务2019-12-02 15:27:00,例如

BEGIN TRAN;
    WAITFOR DELAY '00:03:00';
    
    UPDATE a
    SET account_balance = 999
    FROM dbo.accounts AS a
    WHERE a.id= 'XXXXX'
COMMIT;

我们最后一次加载是在2019-12-02 15:26:00。所以当我们运行 ETL 时,它会得到所有的修改:

SELECT * FROM dbo.accounts WHERE SysSstart > '2019-12-02 15:26:00'

让我们假设 ETL 完成2019-12-02 15:28:00并保存了该值。

由于我们延迟了 3 分钟,因此 UPDATE 完成于2019-12-02 15:30:00,但SysStart列值将2019-12-02 15:27:00与更新事务开始时一样。因此,如果我们再次运行 ETL,则不会加载此事务中更新的记录,因为它们与SysSstart > '2019-12-02 15:28:00'谓词不匹配。

如何处理这种情况?

4

1 回答 1

0

这可能是一个更好的解决方案,但现在我得到了这两个简单的想法(因为您似乎只需要知道最后一次更新发生的时间):

  1. 将 LoadDateTime 添加到您的 dbo.accounts 并在查询中使用它 SELECT * FROM dbo.accounts WHERE LoadDateTime > '2019-12-02 15:26:00'
  2. 在 ETL 开始时保存,而不是在结束时保存
于 2019-12-04T11:26:49.000 回答