eomonth是sql server 2012+内置月末计算函数,支持偏移月数参数(如-1、0、1),自动处理null、跨年及日期边界,比dateadd组合更简洁安全。

直接用 EOMONTH(GETDATE()) 就行,但得确认版本支持
EOMONTH 是 SQL Server 2012 及以上才有的函数,低于这个版本会报错 Invalid object name 'EOMONTH'。如果不确定环境,先执行 SELECT @@VERSION 看下版本号。2012 之后的都支持,不用额外配置或启用功能。
EOMONTH 的第二个参数经常被忽略,但很关键
它接受两个参数:EOMONTH(start_date, [month_to_add])。第一个是起始日期,第二个是偏移月数(可选,默认为 0)。很多人只写 EOMONTH(GETDATE()),没问题;但如果想取“下个月最后一天”,就得写 EOMONTH(GETDATE(), 1);取“上个月最后一天”则是 EOMONTH(GETDATE(), -1)。注意:这个偏移是按日历月算的,不是固定 30 天,所以跨年也安全。
和 DATEADD + DAY 组合比,EOMONTH 更简洁且不易出错
老写法常这样:DATEADD(DAY, -1, DATEADD(MONTH, 1, DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1)))。逻辑绕、易漏括号、对 NULL 不友好。而 EOMONTH 内置处理了边界(比如 1 月 31 日输入仍返回正确月末),还支持列值直接计算,例如:SELECT EOMONTH(OrderDate) FROM Orders。性能上两者差异不大,但可读性和维护性差一截。
遇到 NULL 输入时,EOMONTH 直接返回 NULL,不报错
这是设计行为,不是 bug。如果你的日期字段可能为空,不需要提前 ISNULL 或 CASE 包裹——EOMONTH 本身已做空值穿透。但要注意:如果后续拿结果做比较或计算(比如 WHERE EOMONTH(StartDate) >= '2024-06-30'),NULL 行会被自然过滤掉,这点和其它标量函数一致。别误以为是函数失效。










