【问题标题】:The best mechanism for alter columns of system versioning tables (Temporal Table)?更改系统版本控制表(临时表)列的最佳机制?
【发布时间】:2016-11-01 08:08:43
【问题描述】:

我有一个系统版本控制表,其历史表相关如下:

CREATE TABLE [dbo].[ExpenseCenter_Archive](
    [ExpenseCenterId] [tinyint] NOT NULL,
    [Name] [nvarchar](200) NOT NULL,
    [LineCode] [smallint] NOT NULL,
    [SysStartTime] [datetime2](2) NOT NULL,
    [SysEndTime] [datetime2](2) NOT NULL
) ON [FG_HISTORY]
GO
-------
CREATE TABLE [dbo].[ExpenseCenter](
    [ExpenseCenterId] [tinyint] NOT NULL,
    [Name] [nvarchar](200) NOT NULL,
    [LineCode] [smallint] NOT NULL,
    [SysStartTime] [datetime2](2) GENERATED ALWAYS AS ROW START NOT NULL,
    [SysEndTime] [datetime2](2) GENERATED ALWAYS AS ROW END NOT NULL,
 CONSTRAINT [PK_ExpenseCenter] PRIMARY KEY CLUSTERED 
(
    [ExpenseCenterId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [FG_DATA],
CONSTRAINT [UK_ExpenseCenterName] UNIQUE NONCLUSTERED 
(
    [Name] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [FG_INDEX],
    PERIOD FOR SYSTEM_TIME ([SysStartTime], [SysEndTime])
) ON [FG_DATA]
WITH
(
SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[ExpenseCenter_Archive] , DATA_CONSISTENCY_CHECK = ON )
)
GO

现在,我想在系统版本表和历史记录中更改“LineCode”的数据类型。修改后再次启用如下:

--- Before edit column
ALTER TABLE [dbo].[ExpenseCenter] SET (SYSTEM_VERSIONING = OFF);  
-- ## Edit column in ssms ##

--- After edit column
ALTER TABLE [dbo].[ExpenseCenter] 
SET    
(   
SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[ExpenseCenter_Archive])   
);   

但我收到以下错误:

当未定义 SYSTEM_TIME 时间段时,无法将 SYSTEM_VERSIONING 设置为 ON。

我该如何解决这个问题。

【问题讨论】:

  • 别搞错了!我在alter table 上没有任何错误。它发生在编辑或添加列之后,当我想将 system_versioning 返回到以前的状态(将其设置为“ON”)时,会发生此错误。
  • 我通过删除字段 [SysStartTime][SysEndTime] 来做到这一点。所以看起来不对。
  • 表类型的改变不需要禁用/启用system_versioning。

标签: sql-server sql-server-2016 temporal


【解决方案1】:

根据您的问题,您是说ExpenseCenter_archiveExpenseCenter..的临时表,但错误消息显示

你没有系统版本表[dbo].[ExpenseCenter],如果你想要系统版本表,添加system_time到它

所以这里是步骤,我会按照其他的表格制作一个临时表..

如果它用于新表..

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)   
;  

如果我需要更改这个新创建的表的数据类型..

MSDN recommends doing it in a transaction..

BEGIN TRAN   
ALTER TABLE [dbo].[CompanyLocation] SET (SYSTEM_VERSIONING = OFF);  

ALTER TABLE [CompanyLocation] ADD Cntr INT IDENTITY (1,1);   

ALTER TABLE [dbo].[CompanyLocation]    
SET    
(   
SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[CompanyLocationHistory])   
);   
COMMIT ;  

如果我想将现有的表设为 Temporal,那么我会在下面这样做

ALTER TABLE dbo.Product
ADD StartTime DATETIME2 GENERATED ALWAYS AS ROW START
  HIDDEN DEFAULT GETUTCDATE(),
 EndTime  DATETIME2 GENERATED ALWAYS AS ROW END
  HIDDEN DEFAULT
     CONVERT(DATETIME2, '9999-12-31 23:59:59.9999999'),
 PERIOD FOR SYSTEM_TIME (StartTime, EndTime)

现在终于将时间设置为 ON

ALTER TABLE dbo.Product
SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE=dbo.ProductHistory))
GO

参考资料:
http://sqlhints.com/tag/modify-existing-table-as-system-versioned-temporal-table/
https://msdn.microsoft.com/en-us/library/mt590957.aspx

【讨论】:

  • 别搞错了!我在alter table 上没有任何错误。它发生在编辑或添加列之后,当我想将 system_versioning 返回到以前的状态(将其设置为“打开”)时,会发生此错误。谢谢
  • 请注意,在打开时态表后添加列可能会导致 sp_rename 失败。在交易中执行此操作的重要提示!我使用时态表已经有一段时间了,唯一的抱怨是系统周期存在并发更新问题,这限制了批量更新记录时的吞吐量。
【解决方案2】:

alter system versioning table 不需要设置SYSTEM_VERSIONING = OFF,直接使用ALTER TABLE ...

【讨论】:

  • 历史表与主表同步,所以如果你改变主表的数据类型,历史表会自动改变以匹配。您不必关闭并重新打开系统版本控制。但是,您仍然必须处理 PK、FK 和其他约束。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-17
相关资源
最近更新 更多