【问题标题】:Data sync between temporal tables in SQL ServerSQL Server 中时态表之间的数据同步
【发布时间】:2019-07-03 06:26:15
【问题描述】:

我想在两个具有系统版本(临时)表的数据库之间同步数据。 Azure 中的数据同步选项不支持时态表,我需要找到另一种在数据库之间进行同步的方法。

我想使用 Azure 数据工厂将数据从一个时态表复制到另一个数据库的另一个时态表。Azure 数据工厂是否支持时态表之间的数据同步?

在具有相同时态表的两个数据库之间同步数据的最佳方式是什么?

【问题讨论】:

  • 你的两个数据库都是本地SQL Sverver实例吗?
  • @LeonYue 不,它们不是本地实例,两个数据库位于两个不同的服务器上。
  • 两个不同 Azure SQL 服务器上的两个数据库?
  • @LeonYue 是的,没错

标签: sql-server azure azure-data-factory-2 data-synchronization temporal-tables


【解决方案1】:

我在 Azure SQL 数据库中创建了一个系统版本化(临时)表,遵循此文档Creating a temporal table

CREATE TABLE Department   
(    
     DeptID int NOT NULL PRIMARY KEY CLUSTERED  
   , DeptName varchar(50) NOT NULL  
   , ManagerID INT  NULL  
   , ParentDeptID int NULL  
   , SysStartTime datetime2 GENERATED ALWAYS AS ROW START NOT NULL  
   , SysEndTime datetime2 GENERATED ALWAYS AS ROW END NOT NULL  
   , PERIOD FOR SYSTEM_TIME (SysStartTime, SysEndTime)     
)   
WITH    
   (   
      SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.DepartmentHistory)   
   )   
;

我在不同的 Azure SQL Server 中创建了两个临时表 Department 和 Department2。

我在数据工厂副本活动中测试,选择部门作为源数据集,我们可以从设置中看到时态表:

选择Department2作为链接数据集,表映射::

列映射:

主动运行成功:

这意味着 Azure 数据工厂支持将数据从一个时态表复制到另一个数据库的另一个时态表。

更新:

请参考此文档:Temporal Tables in SQL Server 2016 – Part III

现在,从 INSERT 开始,请记住在声明为 GENERATED ALWAYS AS ROW START / END 的临时表中有两个 datetime2 特殊列。 这些是 PERIOD 列,它们是强制性的,但您不能将显式值插入 GENERATED ALWAYS 列。它的值将被自动填充。 当您在表中插入新行时,“ROW START”列将具有 SYSUTCDATETIME() 值(是的,不要忘记它是 UTC 时间!)并且“ROW END”列将具有值:'9999 -12-31 23:59:59.9999999' 基本上,在临时表中插入新行时,对于这两列,您可以使用以下选项: 1.使用列列表,省略这两列; 2. 使用列列表而不省略这两列,并在每个列的值列表中指定 DEFAULT。 3. 不要使用列列表并在每个列的值列表中指定 DEFAULT。

恭喜,错误已自行解决:

  1. 在关闭目标表的版本控制后加载表,它可以工作。

ALTER TABLE [dbo].[Department] SET(SYSTEM_VERSIONING = OFF); ALTER TABLE [dbo].[Department] DROP PERIOD FOR SYSTEM_TIME;

  1. 然后在复制活动完成后,将其切换回来。
ALTER TABLE [dbo].[Department] ADD PERIOD FOR SYSTEM_TIME (SysStartTime, SysEndTime); ALTER TABLE [dbo].[Department] SET(SYSTEM_VERSIONING = ON);

希望这会有所帮助。

【讨论】:

  • 试过这个并尝试同步一行。但是由于我们无法将显式值添加到 SysStartTime 和 SysEndTime 中而出现以下错误。 "无法将显式值插入到表中的 GENERATED ALWAYS 列中"
  • 感谢@Leon Yeu。但在这种情况下,我们将丢失第一个表中的 sysStartTime 和 SysEndTime,它会插入新值。我想保留第一个表中的 sysStartTime 和 SysEndTime 并在数据同步期间加载它们。
  • @Sindu_如何将数据从一个时态表复制到另一个具有相同架构的普通表?
  • 我在关闭目标表上的版本控制后尝试加载表,它工作正常。 ALTER TABLE [dbo].[部门] SET(SYSTEM_VERSIONING = OFF); ALTER TABLE [dbo].[Department] DROP PERIOD FOR SYSTEM_TIME;
  • 然后我们可以重新打开它:ALTER TABLE [dbo].[Department] ADD PERIOD FOR SYSTEM_TIME (SysStartTime, SysEndTime); ALTER TABLE [dbo].[部门] SET(SYSTEM_VERSIONING = ON);
【解决方案2】:

听起来这个线程得到了它需要的答案,但对于未来的搜索...Azure SQL 数据库中的 Azure SQL 数据同步确实支持同步时态表。

您只需要记住不要同步系统生成的日期列(因为您不能显式插入这些列,数据同步会尝试:-))

https://docs.microsoft.com/en-us/azure/sql-database/sql-database-sync-data#sync-req-lim

HTH

【讨论】:

  • SQL DATA SYNC 工具仅在源表和目标表中的模式匹配时使用,对吧?当架构不同时,您将如何同步 2 个表?
  • @OliverNilsen 您可以指定要同步的列,因此架构不需要完全匹配(目标表只能具有列的子集)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多