【发布时间】:2018-12-06 15:15:16
【问题描述】:
我有一个运行数年数据的 while 循环。在此期间,我需要加入的某些表中的一个属性已更改其名称。为了解决这个问题,我想我可以使用 case 或 if 语句。但我无法让布尔表达式理解或接受我的宏变量中的值。
非常简化(例如,时间很短,while 循环中的所有其他代码都在工作)我的代码如下所示:
declare @StartYear smallint = 2010
declare @Year smallint = @StartYear
declare @EndYear smallint = 2013
declare @YearVC varchar(4) = ''
declare @CreateTable varchar(MAX) = ''
while @Year <= @EndYear
begin
set @YearVC = cast(@Year as varchar)
set @CreateTable = '
if ' + @Year + ' < 2011
select t1.*, t2.a, t2.b, t2.c as e /*Variable t2.e change it´s origin name over time.*/
into ResultTable_' + @YearVC + '
from TableOne_' + @YearVC + ' as t1 left join TableTwo_' + @YearVC + ' as t2 on t1.a=t2.a
if ' + @Year + ' >= 2011
select t1.*, t2.a, t2.b, t2.d as e /*Variable t2.e change it´s origin name over time.*/
into ResultTable_' + @YearVC + '
from TableOne_' + @YearVC + ' as t1 left join TableTwo_' + @YearVC + ' as t2 on t1.a=t2.a
'
exec (@CreateTable)
set @Year = @Year + 1
end
我也尝试过使用 case 语句(所有变量声明、while 循环和 @CreateTAble 语句都是相同的,所以我只在下面编写我的选择语法):
select t1.*, t2.b,
case
when ' + @Year + ' < 2011 then t2.c
else t2.d
end as e
into ResultTable_' + @YearVC + '
from TableOne_' + @YearVC + ' as t1 left join TableTwo_' + @YearVC + ' as t2 on t1.a=t2.a
这两个例子都给了我一个 Msg 245 错误:
转换 varchar 值时转换失败 '
引用我的布尔表达式?
我以多种不同的方式确定了我发送给该表达式的宏变量值不是 varchar。当我尝试使用 varchar 变量时,我收到了 Msg 207 错误:
列名“d”无效。
这意味着它找不到从 2011 年及以后有效的属性的属性名称。
我在这里缺少什么?我应该如何定义我的“if”或“case”语句,以便 SQL-server 能够理解,在 2011 年之前的几年中,它应该寻找属性 c 以及从 2011 年以后的年份,并且应该更进一步寻找属性d?
我使用 MS SQL-server 版本 14。
【问题讨论】:
-
您的语法不正确。在您的第二个查询中,您必须用引号将您的选择括起来。此外,您报告的错误与年份字段有关,该字段是 smallint,您需要将其转换为 varchar 以将其连接到您的字符串
-
对于你的第一次尝试,你必须执行 if out of set 操作,所以'if @year=2011 set ...'
-
谢谢大家!你为我节省了大量时间。
标签: sql if-statement while-loop case