为什么我有多个(未关联的)时间历史表?

MrB*_*MrB 8 sql-server temporal-tables sql-server-2017

我一直在建立一个具有 SQL Server 2017 后端的概念验证系统。
系统使用临时表来记录资产配置并跟踪随时间的变化。
我有一个链接到历史记录表的数据表,我们称之为 dbo.MSSQL_TemporaryHistoryFor_12345678900。

到现在为止还挺好。我有两个问题:

今天我关闭了表格上的版本控制,所以我可以添加一个计算列。这已完成并再次打开,没有错误。

现在我发现我无法查询更改之前的任何历史数据。新数据正在添加到历史记录中,但事先什么也没有。

查看 SSMS 内部,我现在可以看到有多个历史记录表,它们都具有相同的名称但带有十六进制后缀,例如 dbo.MSSQL_TemporaryHistoryFor_12345678900_A0B1C2D3。它们未链接到主数据表下方。它们只是在数据库中自行浮动。当我查询 sys.tables 时,这些没有显示为历史表,也没有链接到主数据表。

这些表确实包含缺失的历史数据。

因此,我的问题是:

  • 这些额外的表代表什么?
  • 它们是如何创建的?
  • 有没有办法以某种方式将这些重新链接到主历史链中,以便我可以取回我的历史报告?

这非常令人沮丧,因此我们将不胜感激地收到您能提供的任何帮助。谢谢。

Jos*_*ell 8

需要提供历史表的名称,以便在关闭和打开系统版本控制时保持数据连续性。ALTER TABLE的文档中提到了这种行为:

如果不使用HISTORY_TABLE参数,系统会生成一个新的与当前表的schema匹配的历史表,在两个表之间建立一个链接,并使系统能够将当前表中每条记录的历史记录在历史表。

这是一个演示。我将从文档中创建示例表:

CREATE TABLE dbo.Employee   
(    
  [EmployeeID] int NOT NULL PRIMARY KEY CLUSTERED   
  , [Name] nvarchar(100) NOT NULL  
  , [Position] varchar(100) NOT NULL   
  , [Department] varchar(100) NOT NULL  
  , [Address] nvarchar(1024) NOT NULL  
  , [AnnualSalary] decimal (10,2) NOT NULL  
  , [ValidFrom] datetime2 (2) GENERATED ALWAYS AS ROW START  
  , [ValidTo] datetime2 (2) GENERATED ALWAYS AS ROW END  
  , PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)  
 )    
 WITH (SYSTEM_VERSIONING = ON);
Run Code Online (Sandbox Code Playgroud)

这会生成一个名为 的历史记录表MSSQL_TemporalHistoryFor_1253579504。现在我将禁用和启用系统版本控制:

ALTER TABLE dbo.Employee SET (SYSTEM_VERSIONING = OFF);
ALTER TABLE dbo.Employee SET (SYSTEM_VERSIONING = ON);
Run Code Online (Sandbox Code Playgroud)

我在你的确切情况下:

在此处输入图片说明


现在我将清理一切:

ALTER TABLE dbo.Employee SET (SYSTEM_VERSIONING = OFF);
DROP TABLE dbo.Employee;
DROP TABLE dbo.MSSQL_TemporalHistoryFor_1253579504;
DROP TABLE dbo.MSSQL_TemporalHistoryFor_1253579504_D0055BB4;
Run Code Online (Sandbox Code Playgroud)

然后创建具有特定历史表名称的表:

 CREATE TABLE dbo.Employee   
(    
  [EmployeeID] int NOT NULL PRIMARY KEY CLUSTERED   
  , [Name] nvarchar(100) NOT NULL  
  , [Position] varchar(100) NOT NULL   
  , [Department] varchar(100) NOT NULL  
  , [Address] nvarchar(1024) NOT NULL  
  , [AnnualSalary] decimal (10,2) NOT NULL  
  , [ValidFrom] datetime2 (2) GENERATED ALWAYS AS ROW START  
  , [ValidTo] datetime2 (2) GENERATED ALWAYS AS ROW END  
  , PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)  
 )    
 WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.EmployeeHistory));  
Run Code Online (Sandbox Code Playgroud)

然后关闭和打开系统版本控制,但继续指定历史表名称:

ALTER TABLE dbo.Employee SET (SYSTEM_VERSIONING = OFF);
ALTER TABLE dbo.Employee SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.EmployeeHistory));
Run Code Online (Sandbox Code Playgroud)

注意:在您的特定情况下,您应该能够使用此语法将丢失的历史表“重新附加”到您的基表

没有额外的表:

在此处输入图片说明

外卖

创建临时表或启用系统版本控制时,始终明确指定历史表名称。

MS 文档现在在“停止系统版本化临时表上的系统版本控制”页面上专门指出了这一点:

重新打开系统版本控制时,不要忘记指定 HISTORY_TABLE 参数。如果不这样做将导致创建一个新的历史表并与当前表相关联。原始历史表仍将作为普通表存在,但不会与当前表关联。