SQL Server 2014如何避免GETDATE()每次访问表时自动更新
解决方案:自动捕获并持久化记录创建时间
针对你在SQL Server 2014里遇到的这个问题,我有几个非常实用的方案推荐,完美匹配你的需求:
1. 核心方案:DEFAULT约束 + 不可更新的日期列
你之前误解了GETDATE()的使用场景——虽然它是非确定性函数,但作为DEFAULT约束时,只会在记录插入的瞬间计算一次值并存储到列中,之后这个值就固定不变了,完全满足持久化的要求。
推荐使用datetime2类型(比传统datetime精度更高,更适合现代应用),配合SYSDATETIME()(比GETDATE()精度更高)作为默认值,示例代码如下:
CREATE TABLE YourTargetTable ( -- 你的其他业务列 Id INT PRIMARY KEY IDENTITY(1,1), -- 创建时间列 CreatedAt DATETIME2(3) NOT NULL DEFAULT SYSDATETIME(), -- 其他业务列... );
DATETIME2(3)表示保留3位毫秒精度,你可以根据需求调整位数(0-7);- 插入记录时不需要手动指定
CreatedAt的值,SQL Server会自动填充当前时间; - 插入完成后,
CreatedAt的值就固定下来,不会随时间变化。
2. 额外保障:防止列被意外修改
如果要确保CreatedAt列不会被人为或程序意外修改,可以添加一个UPDATE触发器来拦截修改操作:
CREATE TRIGGER trg_BlockCreatedAtUpdate ON YourTargetTable AFTER UPDATE AS BEGIN SET NOCOUNT ON; -- 检查是否修改了CreatedAt列 IF UPDATE(CreatedAt) BEGIN RAISERROR('CreatedAt列为记录创建时间,不允许修改', 16, 1); ROLLBACK TRANSACTION; END END;
这样只要有人尝试修改CreatedAt的值,触发器就会抛出错误并回滚事务,彻底保障时间值的持久性。
为什么不推荐其他方案?
- rowversion/timestamp:正如你所说,它是二进制类型,主要用于乐观并发控制,并不是用来表示实际时间的,而且在C#中确实存在IComparer相关的问题,完全不适合用来跟踪记录创建时间;
- 计算列:由于
GETDATE()是非确定性函数,无法用于持久化计算列,所以这个路径走不通。
跟踪最新记录的用法
有了CreatedAt列后,你可以直接通过排序来获取最新记录:
SELECT TOP 1 * FROM YourTargetTable ORDER BY CreatedAt DESC;
内容的提问来源于stack exchange,提问作者chasingD
相关产品推荐
相关产品推荐

