SQL中用@MonthsToGoBack替换固定值时遇标量变量未声明报错咨询
解决SQL Server变量初始化报错问题
报错原因
SQL Server 在DECLARE批量声明变量时,所有变量是同时完成初始化的,无法在同一个DECLARE块中使用刚声明的变量去初始化其他变量。你在声明@StartOfMonth和@EndOfMonth时直接引用了同块内的@MonthsToGoBack,就会触发"未声明标量变量"的错误。
修正后的代码
先声明所有变量,再单独赋值@StartOfMonth和@EndOfMonth,此时@MonthsToGoBack已生效:
DECLARE @MonthsToGoBack INT = -1, @StartOfMonth DATE, @EndOfMonth DATE; -- 用变量计算目标月份的首尾日期 SET @StartOfMonth = DATEADD(m, @MonthsToGoBack, DATEADD(mm, DATEDIFF(m, 0, GETDATE()), 0)); SET @EndOfMonth = DATEADD(d, -1, DATEADD(m, @MonthsToGoBack + 1, DATEADD(mm, DATEDIFF(m, 0, GETDATE()), 0))); SELECT DISTINCT CONVERT(VARCHAR, CompletedDate, 101) AS CompletedDate FROM MyTable WHERE CONVERT(DATE, CompletedDate) BETWEEN @StartOfMonth AND @EndOfMonth;
额外优化方案(SQL Server 2012+)
用EOMONTH和DATEFROMPARTS简化日期计算,代码更易读:
DECLARE @MonthsToGoBack INT = -1, @StartOfMonth DATE, @EndOfMonth DATE; -- 直接生成当前月份偏移指定数量后的月初 SET @StartOfMonth = DATEADD(m, @MonthsToGoBack, DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1)); -- 直接获取月初对应的月末日期 SET @EndOfMonth = EOMONTH(@StartOfMonth); SELECT DISTINCT CONVERT(VARCHAR, CompletedDate, 101) AS CompletedDate FROM MyTable WHERE CONVERT(DATE, CompletedDate) BETWEEN @StartOfMonth AND @EndOfMonth;
内容的提问来源于stack exchange,提问作者user13034980
相关产品推荐
相关产品推荐

