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

SQL Server 2014存储过程跨年度数据返回异常求助

问题分析与解决方案

你的问题出在循环中对@StartMonth的更新逻辑上:当月份超过12时,你只递增了@StartYear,但没有将@StartMonth重置为1。这会导致跨年后,@StartMonth的值会变成13、14……直到超出@EndMonth,循环提前终止,无法生成2018年的月份列。

另外,你的代码里两次重复查询tbl_Consumption,这会降低查询性能,建议用ISNULL或COALESCE来简化逻辑,避免重复子查询。

修正后的代码

DECLARE @StartPeriod DATETIME = N'01/01/2017 00:00:00', @EndPeriod DATETIME = N'12/30/2018 00:00:00'
DECLARE @query VARCHAR(MAX) = '', -- 初始化@query为空字符串,避免初始值为NULL
        @StartMonth int = MONTH(@StartPeriod), 
        @EndMonth int = MONTH(@EndPeriod), 
        @StartYear int = YEAR(@StartPeriod), 
        @EndYear int = YEAR(@EndPeriod), 
        @Period datetime = @StartPeriod

WHILE (@StartYear < @EndYear OR (@StartYear = @EndYear AND @StartMonth <= @EndMonth))
BEGIN
    -- 用ISNULL简化子查询,避免重复查询
    SET @query = @query + ' ISNULL((SELECT Consumption FROM tbl_Consumption c 
                                   WHERE c.ProductID = a.ProductID 
                                     AND YEAR(c.StartPeriod) = ' + CONVERT(VARCHAR, YEAR(@Period)) + '
                                     AND MONTH(c.StartPeriod) = ' + CONVERT(VARCHAR, MONTH(@Period)) + '), 0.00) 
                             AS [Usage (' + LEFT(DATENAME(MONTH, @Period),3) + ' ' + CONVERT(VARCHAR, YEAR(@Period)) + ')],'
    
    SET @Period = DATEADD(MONTH, 1, @Period)
    SET @StartMonth = @StartMonth + 1
    
    -- 当月份超过12时,重置月份为1并递增年份
    IF @StartMonth > 12
    BEGIN
        SET @StartYear = @StartYear + 1
        SET @StartMonth = 1 -- 关键:重置月份为1
    END
END

关键修改点说明

  • 重置@StartMonth为1:在年份递增时,必须把月份重置为1,这样下一轮循环的月份判断才会从1月开始,确保跨年后的所有月份都能被处理。
  • 初始化@query为空字符串:避免@query初始为NULL导致拼接后结果始终为NULL。
  • 简化子查询:用ISNULL包裹子查询,只执行一次消费数据查询,提升性能的同时让代码更简洁。
  • 直接使用YEAR()和MONTH()函数:无需将@Period转为字符串再去解析日期,直接提取年份和月份更高效且避免格式问题。

这样修改后,循环就能正确遍历从2017年1月到2018年12月的所有月份,生成完整的动态列。

内容的提问来源于stack exchange,提问作者Arian Caen Holt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:01:14