Temporal Tables中如何用自定义列替代系统生成的日期列?
Azure SQL Server 自定义列作为时态表周期列解决方案
你遇到的报错是因为时态表默认的GENERATED ALWAYS AS ROW START/END列是系统自动维护的只读列,且你直接替换列名时出现了重复定义冲突,可按如下步骤操作实现用CreatedDate/UpdatedDate作为周期列:
方案1:新表创建流程
- 先创建不带系统版本控制的基础表,保留你需要的自定义时间列
CREATE TABLE dbo.TemporalExample ( [ID] int NOT NULL PRIMARY KEY CLUSTERED , [Name] VARCHAR(100) NOT NULL , [Surname] VARCHAR(100) NOT NULL , [Salary] INT NOT NULL , [CreatedDate] datetime2(2) NOT NULL -- 对应源端生成时间,作为PeriodStart , [UpdatedDate] datetime2(2) NOT NULL -- 对应源端更新时间,作为PeriodEnd );
- 插入所有旧数据,直接给
CreatedDate和UpdatedDate赋值为源端生成的时间即可,此阶段无系统版本控制限制,不会触发报错。 - 将自定义列声明为系统时间周期,开启系统版本控制:
-- 绑定自定义列为周期列,添加自动生成规则 ALTER TABLE dbo.TemporalExample ADD PERIOD FOR SYSTEM_TIME (CreatedDate, UpdatedDate), ALTER COLUMN [CreatedDate] ADD GENERATED ALWAYS AS ROW START, ALTER COLUMN [UpdatedDate] ADD GENERATED ALWAYS AS ROW END; -- 开启系统版本控制,指定历史表 ALTER TABLE dbo.TemporalExample SET (SYSTEM_VERSIONING = ON ( HISTORY_TABLE = dbo.TemporalExample_HistoryTable, DATA_CONSISTENCY_CHECK = ON ));
方案2:已存在默认时态表的调整流程
如果已经创建了带默认PeriodStart/PeriodEnd列的时态表,按如下步骤调整:
- 先关闭系统版本控制
ALTER TABLE dbo.TemporalExample SET (SYSTEM_VERSIONING = OFF);
- 删除原有默认周期配置和列
ALTER TABLE dbo.TemporalExample DROP PERIOD FOR SYSTEM_TIME; ALTER TABLE dbo.TemporalExample DROP COLUMN PeriodStart, PeriodEnd;
- 按方案1的步骤3完成自定义列绑定和版本控制开启即可。
注意事项
- 自定义时间列的类型必须为
datetime2,不可使用datetime/smalldatetime类型,精度可按需设置 - 插入旧数据时必须保证
UpdatedDate >= CreatedDate,否则一致性检查会报错 - 后续常规业务写入时系统会自动维护这两个周期列的值,若需要再次手动写入历史数据,需临时关闭系统版本控制后操作,操作完成后重新开启即可。
内容的提问来源于stack exchange,提问作者John Stud
相关产品推荐
相关产品推荐

