求当月最后一个工作日(排除周六日):SQL自定义函数逻辑错误排查
SQL自定义函数EstDateCheck的逻辑错误排查
核心错误点:
- 返回类型不匹配:函数声明
RETURNS varchar(20),但最终返回的是date类型变量@lastWorkDay,会触发隐式转换,可能导致格式异常或报错。应将返回类型改为date,或显式转换为字符串。 - 日期构造兼容性差:使用
STUFF(@CoustDesireddate, 4, 0, '01/')拼接日期字符串的方式,依赖服务器的日期格式设置,若服务器采用yyyy/mm/dd等非mm/dd/yyyy格式,@testDate的赋值会直接失败。 - 工作日判断依赖系统配置:
DATEPART(WEEKDAY)的返回值由@@DATEFIRST参数决定(比如默认@@DATEFIRST=7时,周日=1、周五=6;若@@DATEFIRST=1,周一=1、周五=5)。原代码中DATEPART(WEEKDAY, ...) <=5的判断仅在特定配置下有效,其他场景会错误排除周五或误判周末为工作日。 - 最后一个工作日计算逻辑错误:当月底为周末时,原计算方式完全错误。例如月底是周日(
DATEPART(WEEKDAY)=1,默认配置),原代码会返回月底前6天的周一,而非正确的月底前2天的周五;若月底是周六,会直接返回周六而非前一天的周五。
修正后的函数代码:
ALTER FUNCTION EstDateCheck (@CoustDesireddate varchar(10)) RETURNS date -- 直接返回date类型,若需字符串可改为varchar(10)并显式转换 AS BEGIN -- 显式转换日期,指定格式101对应mm/dd/yyyy,确保跨环境兼容性 DECLARE @testDate Date = TRY_CONVERT(date, @CoustDesireddate + '/01', 101); DECLARE @endOfMonth date = EOMONTH(@testDate); -- 用DATENAME判断星期几,避免依赖@@DATEFIRST配置 DECLARE @daysToSubtract int = CASE DATENAME(WEEKDAY, @endOfMonth) WHEN 'Saturday' THEN 1 WHEN 'Sunday' THEN 2 ELSE 0 END; DECLARE @lastWorkDay date = DATEADD(DAY, -@daysToSubtract, @endOfMonth); RETURN @lastWorkDay; END
测试执行:
SELECT dbo.EstDateCheck('07/2022') -- 返回2022-07-29(当月正确的最后一个工作日)
内容的提问来源于stack exchange,提问作者Baba Ranjith
相关产品推荐
相关产品推荐

