SQL Server中获取当前时间应使用GETDATE()或SYSDATETIME(),不支持Oracle的SYSDATE;GETDATE()返回datetime(精度3.33毫秒),SYSDATETIME()返回datetime2(7)(精度100纳秒,推荐新项目);存储过程中需在BEGIN内用DECLARE @Now = GETDATE()赋值,不可用于参数默认值;多次调用GETDATE()可能导致时间不一致,应复用变量;注意时区问题,跨地域业务建议用GETUTCDATE()。

SQL Server里用GETDATE()获取当前时间,不是SYSDATE
SQL Server不支持SYSDATE——那是Oracle、MySQL(部分模式)或PostgreSQL的函数。在SQL Server存储过程中,必须用GETDATE()或更精确的SYSDATETIME()。直接写SYSDATE会报错:Invalid column name 'SYSDATE'。
常见错误场景:从Oracle迁移脚本时忘了替换函数名;或者查资料时混淆了不同数据库的语法。
-
GETDATE()返回datetime类型(精度到3.33毫秒,范围1753–9999年) -
SYSDATETIME()返回datetime2(7)(精度100纳秒,推荐新项目使用) - 若需带时区信息,用
SYSDATETIMEOFFSET()
在存储过程中声明并使用当前时间变量
不能直接在参数默认值里调用GETDATE()(SQL Server不支持函数作为标量参数默认值),必须在过程体内部赋值。
CREATE PROCEDURE LogOperation
AS
BEGIN
DECLARE @Now DATETIME = GETDATE(); -- ✅ 正确:在BEGIN内赋值
INSERT INTO OperationLog (EventTime, Action)
VALUES (@Now, 'User login');
END
注意:DECLARE ... = GETDATE()是SQL Server 2008+才支持的简写,旧版本需分开写:DECLARE @Now DATETIME; SET @Now = GETDATE();
避免把GETDATE()当常量反复调用
同一个存储过程里多次调用GETDATE(),可能返回略微不同的值(尤其跨毫秒边界时),导致逻辑不一致。比如日志时间戳、计算超时、生成唯一标识等场景都受影响。
- ✅ 正确做法:一次获取,多次复用
@Now变量 - ❌ 错误做法:
WHERE CreateTime > GETDATE() - 1和INSERT ... VALUES(GETDATE())分开调用 - 性能上无差异,但语义和可维护性差——后续想统一加时区偏移或调整精度时,得改多处
跨数据库兼容?别硬套,优先明确目标平台
如果真需要写“一套SQL跑多个数据库”,不要试图用条件函数模拟SYSDATE,而应通过应用层或部署脚本做方言适配。SQL Server里强行用CREATE FUNCTION SYSDATE() RETURNS DATETIME AS BEGIN RETURN GETDATE(); END看似可行,但会带来额外开销、权限问题,且无法在索引视图或某些上下文中使用。
真正容易被忽略的是时区——GETDATE()返回的是服务器本地时间,不是UTC,也不是客户端所在时区。如果业务涉及多地用户,存时间前务必确认是否该用GETUTCDATE(),以及前端如何解析显示。










