SQL Server时态表自连接查询可靠性:ValidFrom与ValidTo关联疑问
关于SQL Server时态表自连接条件的解答
问题背景
你使用SQL Server系统版本时态表已有一段时间,需要编写自连接查询找出MyValue从'A'变更为'B'的记录,当前查询语句如下:
SELECT t1.Id, t1.MyValue OldValue, t2.MyValue NewValue, t2.ValidFrom DateChanged FROM MyTable FOR SYSTEM_TIME ALL t1 JOIN MyTable FOR SYSTEM_TIME ALL t2 ON t2.Id = t1.Id AND t2.ValidFrom = t1.ValidTo WHERE t1.MyValue = 'A' AND t2.MyValue = 'B';
你对连接条件t2.ValidFrom = t1.ValidTo的可靠性存在疑问,具体咨询两个问题:
- 历史记录中,后续记录的ValidFrom是否始终等于前一条记录的ValidTo?序列中是否存在间隔?
- 历史表中是否可能存在两条记录的ValidFrom日期相同?
问题解答
1. 记录序列的连续性
SQL Server系统版本时态表会自动保证同一主键(Id)的记录序列连续性:
- 当对某条记录执行更新或删除操作时,系统会将旧版本写入历史表,同时把旧记录的
ValidTo设为当前事务的开始时间戳(精度为datetime2,默认到微秒级别); - 新版本记录(或删除后保留的当前版本标记)的
ValidFrom会被设置为完全相同的时间戳。 - 只要是系统自动维护的记录(未手动修改历史表或当前表的
ValidFrom/ValidTo列),同一Id的记录序列中不会出现间隔,后续记录的ValidFrom必然等于前一条的ValidTo。
2. 同一Id的ValidFrom重复问题
对于同一主键(Id)的记录,历史表中不可能出现两条ValidFrom相同的记录:
- 每次针对同一行的修改操作都是原子性的,一个事务中对同一行的修改只会生成一条历史记录,
ValidFrom被统一设为事务开始的时间戳; - 不同事务对同一行的修改会有不同的时间戳(即使间隔极短,
datetime2的精度也能区分)。 - 但如果是不同Id的记录,它们的
ValidFrom可以相同——比如在同一个事务中批量修改多条不同的记录,这些记录的ValidFrom都会被设为事务开始时间。
补充说明
你的查询语句在系统正常维护时态表的情况下是完全可靠的。只有当有人手动修改过ValidFrom/ValidTo列(这是不推荐的操作,会破坏时态表的完整性),才可能出现连接条件不匹配的情况。
内容的提问来源于stack exchange,提问作者PaulH567
相关产品推荐
相关产品推荐

