You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在时态表中排除指定列不存入对应的历史表?

实现时态表排除指定字段不记录历史的方法

针对你希望Data2字段变更不存入SampleHistory历史表的需求,有两种可靠的实现方式:

方法一:拆分表结构(推荐)

将需要审计的字段和无需审计的字段分离为两个表,仅对含审计字段的表启用系统版本控制,从根源上避免非审计字段生成历史记录:

  1. 创建带系统版本控制的主表(仅包含需要审计的字段):
CREATE TABLE dbo.Sample
(
  SampleId int identity(1,1) PRIMARY KEY CLUSTERED
  , SampleDate date NOT NULL
  , Data1 varchar(50)
  , SysStartTime datetime2 GENERATED ALWAYS AS ROW START
  , SysEndTime datetime2 GENERATED ALWAYS AS ROW END
  , PERIOD FOR SYSTEM_TIME (SysStartTime, SysEndTime)
)
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.SampleHistory));
  1. 创建独立表存储无需审计的Data2字段:
CREATE TABLE dbo.SampleNonAudit
(
  SampleId int PRIMARY KEY FOREIGN KEY REFERENCES dbo.Sample(SampleId)
  , Data2 varchar(50)
);

后续SampleNonAudit表的任何变更都不会生成历史记录,仅Sample表的字段变更会被SampleHistory追踪,既节省存储空间又满足审计需求。

方法二:自定义触发器替代系统版本控制(按需使用)

如果无法拆分表结构,可关闭原生系统版本控制,改用触发器手动记录指定字段的变更:

  1. 先关闭原时态表的系统版本控制并删除自动生成的历史表:
ALTER TABLE dbo.Sample SET (SYSTEM_VERSIONING = OFF);
DROP TABLE dbo.SampleHistory;
  1. 手动创建仅包含审计字段的历史表:
CREATE TABLE dbo.SampleHistory
(
  SampleId int
  , SampleDate date NOT NULL
  , Data1 varchar(50)
  , SysStartTime datetime2
  , SysEndTime datetime2
  , PRIMARY KEY (SampleId, SysStartTime)
);
  1. 创建触发器,仅在审计字段变更时写入历史记录:
-- INSERT触发器:记录新数据的初始状态
CREATE TRIGGER trg_Sample_Insert
ON dbo.Sample
AFTER INSERT
AS
BEGIN
  INSERT INTO dbo.SampleHistory (SampleId, SampleDate, Data1, SysStartTime, SysEndTime)
  SELECT SampleId, SampleDate, Data1, SYSUTCDATETIME(), '9999-12-31 23:59:59.9999999'
  FROM inserted;
END;

-- UPDATE触发器:仅当审计字段变更时更新历史
CREATE TRIGGER trg_Sample_Update
ON dbo.Sample
AFTER UPDATE
AS
BEGIN
  -- 仅在SampleDate或Data1变更时执行历史记录逻辑
  IF UPDATE(SampleDate) OR UPDATE(Data1)
  BEGIN
    -- 标记原记录的结束时间
    UPDATE h
    SET h.SysEndTime = SYSUTCDATETIME()
    FROM dbo.SampleHistory h
    JOIN deleted d ON h.SampleId = d.SampleId
    WHERE h.SysEndTime = '9999-12-31 23:59:59.9999999';

    -- 插入新记录的当前状态
    INSERT INTO dbo.SampleHistory (SampleId, SampleDate, Data1, SysStartTime, SysEndTime)
    SELECT SampleId, SampleDate, Data1, SYSUTCDATETIME(), '9999-12-31 23:59:59.9999999'
    FROM inserted;
  END;
END;

注意:SQL Server原生系统版本时态表的设计是追踪全字段变更,没有直接排除指定字段的配置项,因此上述两种方法是当前可行的替代方案。

内容的提问来源于stack exchange,提问作者sorosh_sabz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 17:55:17