2

我最近将我的 SQL 2019 数据库从 VM 迁移到 Azure SQL。我使用了 MS 数据迁移工具,但不幸的是,它不会从临时表迁移数据。

所以。我只是使用该工具创建表模式,然后使用 SSIS 移动数据。

由于我现有的历史表中有数据,我想保留 SysStartDate 和 SysEndDate 字段。为了做到这一点,我必须在我的 Azure SQL 数据库中禁用 SYSTEM_VERSIONING 并在表上删除 PERIOD。

数据迁移成功,所以我在表上重新创建了我的 PERIOD,但是当我尝试使用指定的历史表启用 SYSTEM_VERSIONING 时,我收到以下错误:

消息 13573,级别 16,状态 0,第 34
行将 SYSTEM_VERSIONING 设置为 ON 失败,因为历史表 'xxxxxHistory'
包含重叠记录。

我觉得这很奇怪,因为现有表最初是作为临时表加入的,所以我不明白为什么现在会发生冲突。

ALTER TABLE xxx.xxx 
ADD PERIOD FOR SYSTEM_TIME(SysStartTime, SysEndTime)    

ALTER TABLE xxx.xxx 
SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE=xxx.xxxHistory))

我希望得到一个成功的临时表。相反,我收到以下错误:

消息 13573,级别 16,状态 0,第 34
行将 SYSTEM_VERSIONING 设置为 ON 失败,因为历史表 'xxxxxHistory'
包含重叠记录。

我运行以下查询来识别重叠,但我没有得到任何:

SELECT 
     xxxxKeyNumeric
     ,SysStartTime
     ,SysEndTime
FROM 
    xxxx.xxxxhistory o
WHERE EXISTS
(
    SELECT 
        1 
    FROM 
        xxxx.xxxxhistory o2
    WHERE 
        o2.xxxxKeyNumeric = o.xxxxKeyNumeric
        AND o2.SysStartTime <= o.SysEndTime
        AND o.SysStartTime <= o2.SysEndTime
        AND o2.xxxxPK != o.xxxxPK
)
ORDER BY 
    o.xxxxKeyNumeric, 
    o.SysStartTime
4

2 回答 2

2

我发现了这个错误的解释:

“同一条记录有多个记录,开始日期和结束日期重叠。历史表中最后一行的结束日期应与父表中活动记录的开始日期匹配” DBA 的博客

这发生在我切换历史表后,触摸几行,然后试图回到旧的历史表。

更新:再次发生,这次表有数百万行。我必须编写一个查询,比较历史表中每一行的开始日期和结束日期。

可能的原因:

  1. 对于每个 PK,历史记录行的开始日期和结束日期不得重叠。 下面的查询将找到这个特定的问题。
  2. 该 PK 历史记录中最新行的结束日期,其结束日期晚于主表中 PK 的开始日期。可以修改上面的查询来做到这一点
  3. 在具有相同PK的行中,2行覆盖相同的时间间隔。如果它们重叠一毫秒,​​并且有人要求精确的毫秒,它将不知道这两个版本中的哪一个是正确的。

对于第一个问题:

select ant.*,post.* , DATEDIFF(day,ant.end_date,post.start_date)
from
(SELECT
      PK_column
    , start_date
    , end_date
    , ROW_NUMBER() OVER(PARTITION BY PK_column ORDER BY end_date desc, start_date desc)    AS current
    ,(ROW_NUMBER() OVER(PARTITION BY PK_column ORDER BY end_date desc, start_date desc))-1 AS previous
FROM huge_table_HIST 
) ant
inner join
(SELECT
      key_column
    , start_date
    , end_date
    , ROW_NUMBER() OVER(PARTITION BY PK_column ORDER BY end_date desc, start_date desc ) AS current
    FROM huge_table_HIST 
) post
ON ant.PK_column=post.PK_column AND ant.previous=post.current
WHERE ant.end_date > post.start_date

令人惊讶的是,如果:

  • 对于同一个 PK,您有多行具有完全相同的开始结束日期和结束日期。SQL Server 似乎将它们视为空间中的一个点,而不是一个间隔。只有当您请求它们存在的确切毫秒数时,它们才会出现。
  • 历史记录行的结束日期与下一个记录行的开始日期之间存在间隔。SQL 服务器认为 PK 只是在那个时间间隔内不存在。
于 2020-07-08T17:07:29.100 回答
0

时态表依赖于时态表的主键值与 SysStartTime 结合确定历史表中的唯一性。

如果您更改主键定义,这很容易发生。此外,如果未填充与时态表的 PK 对应的历史表字段,或者许多/全部填充了默认值,则会检测到重叠并出现该错误。

检查您的 PK 是否在系统版本化的临时表上定义,然后检查您的历史记录表的主键字段中的相应值是否正确(即对于任何给定的 PK 和 SysStartTime 值都是唯一的。)

在再次应用系统版本控制关系之前,您可能必须相应地更新历史记录表。

于 2019-11-01T21:31:25.297 回答