sql server 没有真正的隐藏列功能;所谓“隐藏列”是误传,实际指时态表系统时间列(默认不显示于select *)、ssms ui过滤或计算列等混淆概念,无hidden语法支持。

SQL Server 本身没有“隐藏列”这个功能概念,所谓“隐藏列”是误传或混淆了其他机制(比如系统版本控制、计算列、或 SSMS 的 UI 隐藏选项)——你无法像 Excel 那样把一列设为“隐藏但存在”,然后靠它自动追踪修改。
SQL Server 没有真正的 hidden column 语法支持
你查不到 ALTER TABLE ... ADD COLUMN hidden 或 HIDDEN 关键字;SQL Server 的 sys.columns 中也没有 is_hidden 这类原生字段(那是 SQL Server 2016+ 对 GENERATED ALWAYS AS ROW START/END 列的内部标记,不可手动设置)。所谓“隐藏列”在官方文档里只出现在时态表(Temporal Tables)中对系统时间列的描述——它们默认不显示在 SELECT * 结果里,但本质仍是普通列,且必须显式定义。
- 试图用
ALTER TABLE ... ADD modified_at DATETIME2 HIDDEN会报错:Incorrect syntax near 'HIDDEN' - SSMS 中右键表 → “设计” → 取消勾选某列的“可见”复选框?那只是 UI 过滤,不影响查询或存储
- 某些 ORM 或 BI 工具的“隐藏字段”设置,仅作用于其自身界面,和数据库无关
真正能追踪修改的可行方案只有三种
如果你目标是自动记录谁、何时、改了什么,必须靠显式设计,而不是幻想“隐藏列”帮你默默干活:
-
时态表(SYSTEM_VERSIONED_TEMPORAL_TABLE):唯一接近“自动追踪”的内置方案。需定义两个
DATETIME2列(如ValidFrom/ValidTo),并启用版本控制。SQL Server 自动维护历史表,但这两列会出现在SELECT *中(除非你SELECT col1, col2 FROM t显式排除) -
AUDIT + DML 触发器:在目标表上建
AFTER UPDATE, INSERT, DELETE触发器,把INSERTED/DELETED内容 +SYSTEM_USER+GETDATE()写入审计日志表。可控性强,但触发器影响写入性能,且需自己处理多列变更比对 -
应用层打点 + 修改时间戳列:最轻量。加一个
last_modified DATETIME2列,每次UPDATE时显式赋值GETUTCDATE();配合应用代码确保所有更新都带该字段。不记录旧值、不记录操作人,但简单可靠
为什么有人误以为有 hidden column?
常见混淆来源:
- 执行
SELECT * FROM sys.tables时,SSMS 默认折叠部分系统列(如is_ms_shipped),让人误以为“被隐藏了”——其实只是客户端行为 - 创建时态表后,运行
SELECT * FROM dbo.MyTable看不到ValidFrom/ValidTo?那是 SSMS 的 bug 或缓存问题;实际它们一定存在,且SELECT ValidFrom FROM dbo.MyTable肯定能查到 - 某些文章把
AS PERSISTED计算列说成“隐藏”,但计算列可被查询、索引、甚至WHERE引用,和“隐藏”毫无关系
真要追踪修改,别找“隐藏列”,老老实实选时态表、触发器或应用层时间戳——三者选哪个,取决于你是否需要历史快照、能否接受额外维护成本、以及有没有权限开时态功能。漏掉 ValidFrom 的 NOT NULL 约束、或忘了在触发器里处理 NULL 值,比纠结“隐藏”二字容易踩得多。











