You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修改SQL查询解决SSRS校历报表假期运行失效且无法改表问题

问题背景

这是我之前提出的问题的后续,原问题为Stack Overflow上的《SQL Query to pull date range based on dates in a table》。

我查询的数据库里,dbo.TblSchoolManagementTermDates表存储了学校的学期日期,但没有包含假期的日期范围。这就导致按计划每周一运行的报表如果刚好赶上假期,会因为参数无效运行失败被禁用,我得等开学后重新手动启用报表。

我们没有权限给这个表加额外的行,所以只能修改查询来获取适配的日期。理想状态是假期时报表不用实际出数据但保持启用状态,等下次运行日期落到学期内再正常执行,但SSRS的定时调度没有这么灵活的配置项。

我想到了两种可行的方案:

  • 第一种:匹配不到学期日期时,把报表触发当日同时赋值给txtStartDate和txtFinishDate字段,收件人收到无效报表直接删掉邮件就行。
  • 第二种:报表统一按学年(每年9月1日到次年8月31日)返回日期范围,自动匹配正确年份,比如2022年1月1日运行报表时,返回开始日期2021年9月1日,结束日期2022年8月31日。

我现在用的SQL查询如下:

SELECT
    CONVERT(varchar(17), MIN(txtStartDate), 111) AS start_date,
    CONVERT(varchar(17), MAX(txtFinishDate), 111) AS end_date
FROM  TblSchoolManagementTermDates
WHERE (CONVERT(date, GETDATE()) BETWEEN txtStartDate AND txtFinishDate)

欢迎提供符合需求的修改方案,也可以提出其他可行思路,提前感谢。

Stuart

附相关说明:

  • 学期日期表结构可参考截图:学期日期表
  • 当前查询当日运行输出结果参考:当前查询运行输出
  • 补充规则:每学年分3个学期,时段为9月1日至次年8月31日,可直接用该时段作为学年统计范围。两种方案的具体要求:第一种是查询不到匹配的学期日期时,直接返回报表运行当日作为起止日期;第二种是无论运行日期是否在学期内,都返回当前所属学年的起止日期,即2021年9月1日至2022年8月31日之间的任意日期运行,都返回2021-09-01为开始日期、2022-08-31为结束日期,规则需每年动态生效。

解决方案

下面分别提供两种方案的实现代码,可根据实际需求选择:

方案1:无匹配学期时返回当日作为起止日期

用COALESCE处理空值,当原查询没有返回结果时,自动填充当前日期作为起止日期,改动最小,完全兼容原有逻辑:

SELECT
    COALESCE(CONVERT(varchar(17), MIN(txtStartDate), 111), CONVERT(varchar(17), GETDATE(), 111)) AS start_date,
    COALESCE(CONVERT(varchar(17), MAX(txtFinishDate), 111), CONVERT(varchar(17), GETDATE(), 111)) AS end_date
FROM  TblSchoolManagementTermDates
WHERE (CONVERT(date, GETDATE()) BETWEEN txtStartDate AND txtFinishDate)

假期时返回起止日期相同的结果,不会触发SSRS参数校验错误,报表不会被禁用。

方案2:始终返回当前所属学年的起止日期

先动态计算当前日期对应的学年度起止时间,不管是否在学期内都返回固定的学年范围:

DECLARE @CurrentDate DATE = GETDATE()
DECLARE @AcademicStart DATE, @AcademicEnd DATE

-- 动态计算学年开始日期:如果当前月份>=9,学年从今年9月1日开始,否则从去年9月1日开始
SET @AcademicStart = CASE WHEN MONTH(@CurrentDate) >=9 
                          THEN DATEFROMPARTS(YEAR(@CurrentDate),9,1)
                          ELSE DATEFROMPARTS(YEAR(@CurrentDate)-1,9,1)
                     END
-- 学年结束日期为开始日期加1年减1天
SET @AcademicEnd = DATEADD(DAY, -1, DATEADD(YEAR, 1, @AcademicStart))

SELECT
    CONVERT(varchar(17), @AcademicStart, 111) AS start_date,
    CONVERT(varchar(17), @AcademicEnd, 111) AS end_date

如果需要优先取当前所在学期的起止,没有匹配项再返回学年范围,可使用合并版本:

DECLARE @CurrentDate DATE = GETDATE()
DECLARE @TermStart DATE, @TermEnd DATE
DECLARE @AcademicStart DATE, @AcademicEnd DATE

-- 计算学年起止
SET @AcademicStart = CASE WHEN MONTH(@CurrentDate) >=9 
                          THEN DATEFROMPARTS(YEAR(@CurrentDate),9,1)
                          ELSE DATEFROMPARTS(YEAR(@CurrentDate)-1,9,1)
                     END
SET @AcademicEnd = DATEADD(DAY, -1, DATEADD(YEAR, 1, @AcademicStart))

-- 查询当前学期起止
SELECT 
    @TermStart = MIN(txtStartDate),
    @TermEnd = MAX(txtFinishDate)
FROM TblSchoolManagementTermDates
WHERE @CurrentDate BETWEEN txtStartDate AND txtFinishDate

-- 优先返回学期范围,无匹配则返回学年范围
SELECT
    CONVERT(varchar(17), COALESCE(@TermStart, @AcademicStart), 111) AS start_date,
    CONVERT(varchar(17), COALESCE(@TermEnd, @AcademicEnd), 111) AS end_date

内容的提问来源于stack exchange,提问作者Stuart Winfield

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 08:15:03